4

MATLABで以下をコーディングするのは非常に困難です。次のベクトルがあるとします。

a   
b
c
d
e
f
g
h
...

(偶数)ウィンドウサイズを指定して、L行ごとの次元の次の行列を作成しnます(例、L = 4)。

a c e ...
b d f ...
c e g ...
d f h ...

さらに難しいのは、任意の長さのベクトルを取得し、ウィンドウの数を指定し、ウィンドウサイズを最適化(最大化)して、ベクトルの最後にダンプされる値が少なくなるようにすることです。

4

4 に答える 4

4

短い答え

bsxfunこの場合はあなたの友達です。次のワンライナーL(あなたが知ってvいて、あなたのベクトルであると仮定して)はあなたが望むことをします

v(bsxfun(@plus, [0:L-1]', 1:L/2:numel(v)-L))

説明

それを試して理解するために、さらに見てみましょう。アイデアは、最初に、ウィンドウがベクトルのどこから始まるかを決定するベクトルを作成することvです。WindowsはすべてのL/2エントリを開始します(L偶数なので、分割できます)。しかし、いくつのウィンドウが収まりますか?これを理解するには、MATLABを使用して次のように言うことができます。

start_offset = 1:L/2:numel(v)-L;

ここでは、それを指定するだけです。

  • 最初のウィンドウはインデックス1にあります
  • WindowsはすべてのL/2エントリを開始します
  • 最後のウィンドウは、vベクトルが終了する前に少なくともL個のエントリを開始する必要があります。そこに最後の窓がこぶしになるように。

さて、残りの例:

v = 'a':'z';
L = 4;

% indices in every output matrix column are contiguous
% and the difference between first and last is `L-1`
id1 = [0:L-1]';

% start_offset determines where in the input vector v every window starts.
% windows start every L/2 entries. The last entry that fits will start
% at some index, from which we can still use L subsequent indices to access v
start_offset = 1:L/2:numel(v)-L;

% calculate how many entries were dropped from v
% from number of elements in v subtract the largest index value used
dropped = numel(v) - (start_offset+L-1);

% window indices are created using bsxfun and singleton expansion.
% Every window's indices are given by [0:L-1] + window start index
idx = bsxfun(@plus, id1, start_offset);

v(x)

ans =

  acegikmoqsu
  bdfhjlnprtv
  cegikmoqsuw
  dfhjlnprtvx
于 2012-10-19T05:29:11.823 に答える
4

インデックスのマトリックスをベクトルに作成します。L = 4の場合(L / 2でオーバーラップしていると思います)、インデックスは[1,2,3,4;3,4,5,6;5,6,7,8]などです。x=1とします。 :L、y = L / 2、インデックスのベクトルはx + 0y、x + 1y、x+2yなどです。

% let your initial data be in vector "data"
L = 4
N = floor(length(data)/(L/2))-1 % number of windows, or you specify this
mi = repmat(1:L,[N,1]) + repmat((L/2) * (0:(N-1))',[1,L]) % x + y * 0,1,2...
out = data(mi) % out is N-by-L, transpose to L-by-N if you like
于 2012-10-19T02:40:07.833 に答える
2

やりたいことを行う一般的な方法は次のとおりです。

1)適切なウィンドウ幅(および対応するシフト)を計算します
。2)ウィンドウを各列にシフトする量だけ1から繰り返して、各列の開始インデックスを最終値まで決定します。これを行ベクトルにします。
3)bsxfunこれをインデックスのマトリックスに拡張するために使用します。
4)インデックスを使用して、元のベクトルから値を取得します。

vec = 1:17; #% original data vector
num_windows = 3; #% specified number of windows
possible_window_length = 1:length(vec);
window_length = possible_window_length(find(possible_window_length +...
    (num_windows-1) * possible_window_length/2 < length(vec),1,'last'));
window_shift = floor(window_length)/2;
window_length = window_shift * 2; #% calculated window length
max_final_start_index = (length(vec)-window_length+1);
start_indices = 1:window_shift:max_final_start_index;
inds = bsxfun(@plus,start_indices,(0:window_length-1)');
soln = vec(inds); #% get the solution
num_excluded_vals = max_final_start_index - start_indices(end)
disp(soln);
num_excluded_vals =  1
disp(soln);
    1    5    9
    2    6   10
    3    7   11
    4    8   12
    5    9   13
    6   10   14
    7   11   15
    8   12   16
于 2012-10-19T02:57:33.927 に答える
1

インデックス、手続き型アプローチ、ベクトル化されたソリューションなどを操作することにより、MATLABでこれを行う方法はたくさんあります。それでも、MATLABがの機能スタイルを少しサポートしていれば、いくつかのタスクがどれほど単純になるかを考えずにはいられません。プログラミング。その精神で、私は次の解決策を提示します。定義時に、これらの変数にまだ値がないことを確認してください。

take=@(mat,n)mat(1:n)
partition=@(mat,L)cell2mat(arrayfun(@(x)take(circshift(mat(:),-x*L/2),L),...
        0:fix((length(mat)-L)/2+1)-1,'UniformOutput',0))

次に、テストベクトルで試してください。

partition(1:10,4)

 %ans = 
 %    1     3     5     7
 %    2     4     6     8
 %    3     5     7     9
 %    4     6     8    10

L上記の解決策は、分割後の長さに合わないベクトルの最後の最終値を破棄します。これに基づいて、他の配置を処理し、エンドの無駄を最小限に抑えるための最適なウィンドウの長さなどを把握できます。

于 2012-10-19T03:39:45.823 に答える