2

3 つの要素を持つセル配列があるとします。1 番目と 3 番目のセルは行列で、2 番目のセルは空です。

>> P
P = 
  [3x8 double]    []    [3x8 double]

マトリックス内の個々の要素ごとに補間することで 2 番目のマトリックスを埋めることができますが、これを 1 回で行う方法があるはずです。

編集: 平均は確かに P で機能します。しかし、次のようなものがあるとします。

>> Q
Q = [3x8 double]    [3x8 double]     [3x8 double]    []    []    [3x8 double]

したがって、既知の 4 つの行列が与えられた場合、(スプラインなどの) 手の込んだ補間を使用して、欠落している行列を埋めることができます。

4

3 に答える 3

4

INTERP1への1回の関数呼び出しですべての補間を実行できますが、データを目的の形状に設定してから、実行したら元に戻す必要があります。

%# cell array of matrices (some are missing)
sz = [3 8];         %# all of same size
Q = {ones(sz), [], 3*ones(sz), [], [], 6*ones(sz)};

%# indices of missing matrices
idx = ~cellfun(@isempty,Q);
x = 1:numel(Q);

%# merge cells into a multidimensional matrix, call INTERP1, then divide back
QQ = Q(idx);
QQ = permute(cat(3,QQ{:}), [3 1 2]);
QQ = interp1(x(idx), QQ, x);            %# one call to interpolation function
QQ = reshape(num2cell(permute(QQ, [2 3 1]), [1 2]), 1,[]);

ベクトル化には読みやすさが犠牲になることがあることを覚えておいてください...

于 2012-05-31T23:23:51.357 に答える
2

このようなものはあなたのおもちゃのケースで機能します:

l = length(P{1}(:)); m = size(P{1}, 1); n = size(P{1}, 2);
myfun = @(x) interp1([1 3], [P{1}(x) P{3}(x)], 2)
P{2} = reshape(arrayfun(myfun, 1:l), m, n);

一般的に機能するより一般的なコード(検証済み!!)。1回のinterp1呼び出しで使用する補間のタイプを指定できます。

[m, n] = size(P{1}); l = m*n;
avbl = find(not(cellfun('isempty', P)));
missing = find(cellfun('isempty', P));

extractor = @(k) cellfun(@(x, k) x(k), {P{avbl}}, cellmat(1, length(avbl), 1, 1, k))
myfun = @(x) interp1(avbl, extractor(x), missing)
intermediate = reshape(arrayfun(myfun, 1:l, 'UniformOutput', false), m, n);
ext2 = @(k) cellfun(@(p) p(k), intermediate);
P(missing) = arrayfun(ext2, 1:length(missing), 'UniformOutput', false);

いくつかの部分について説明してほしい場合はお知らせください。基本的には、cellfunを数回呼び出してから、出力を再形成するだけです。

于 2012-05-31T22:37:25.870 に答える
0

つまり:

     p{2} = (p{1} + p{3}) / 2;  % note the curly braces

?

于 2012-05-31T22:39:41.040 に答える