を使用して通常の補間を適用するinterp1
と、手で計算した結果が得られます。
>> N = 9;
>> B = interp1(linspace(0,1,numel(A)), A, linspace(0,1,N), 'nearest')
B =
1 4 4 7 4 4 3 3 6
少し前に、IMRESIZE のソース コードを調べて、それがどのように機能するかを理解しようとしました。概要については、この投稿を参照してください。ある時点で、コードはプライベート MEX 関数を呼び出します (対応するソース コードは利用できません) が、コメントは実装を理解するのに十分です。
価値があるのは、 (バージョン R2006b 以前で使用されていた)imresize_old
の古い実装を提供する関数もあります。imresize
さらに別の結果が得られました。
>> B = imresize(A, [1 N], 'nearest')
B =
1 4 4 7 4 4 3 6 6
>> B = imresize_old(A, [1 N], 'nearest')
B =
1 4 4 7 7 4 3 6 6
さらに、 MATLABとOctaveの間の実装も場合によっては異なることが以前に観察されました。
編集:
ご指摘のとおり、場合によっては、 を使用する際に浮動小数点の制限に注意する必要がありますinterp1
。したがって、x 番号を[0,1]
範囲内、または のようなより安定した範囲に選択することで、補間を行うことができます[1,numel(A)]
。エッジ ケースでの丸め誤差のため、これは異なる結果になる可能性があります。
たとえば、次の 2 つのコードを比較します。
% interpolation in [0,1]
N = 11;
y = [1 4 7 4 3 6];
x = linspace(0,1,numel(y));
xi = linspace(0,1,N);
yi = interp1(x, y, xi, 'nearest');
% print numbers with extended precision
fprintf('%.17f %g\n',[x;y])
fprintf('%.17f %g\n',[xi;yi])
に対して:
% interpolation in [1,k]
N = 11;
y = [1 4 7 4 3 6];
x = 1:numel(y);
xi = linspace(1,numel(y),N);
yi = interp1(x, y, xi, 'nearest');
% print numbers with extended precision
fprintf('%.17f %g\n',[x;y])
fprintf('%.17f %g\n',[xi;yi])
きれいにフォーマットされた出力は次のとおりです。
--------------------------------------------------------
[0,1] RANGE | [1,k] RANGE
--------------------------------------------------------
xi yi | xi yi
--------------------------------------------------------
0.00000000000000000 1 | 1.00000000000000000 1 |
0.20000000000000001 4 | 2.00000000000000000 4 |
0.40000000000000002 7 | 3.00000000000000000 7 |
0.59999999999999998 4 | 4.00000000000000000 4 | INPUT
0.80000000000000004 3 | 5.00000000000000000 3 |
1.00000000000000000 6 | 6.00000000000000000 6 |
--------------------------------------------------------
0.00000000000000000 1 | 1.00000000000000000 1 |
0.10000000000000001 4 | 1.50000000000000000 4 |
0.20000000000000001 4 | 2.00000000000000000 4 |
0.29999999999999999 4 | 2.50000000000000000 7 |
0.40000000000000002 7 | 3.00000000000000000 7 |
0.50000000000000000 4 | 3.50000000000000000 4 | OUTPUT
0.59999999999999998 4 | 4.00000000000000000 4 |
0.69999999999999996 4 | 4.50000000000000000 3 |
0.80000000000000004 3 | 5.00000000000000000 3 |
0.90000000000000002 6 | 5.50000000000000000 6 |
1.00000000000000000 6 | 6.00000000000000000 6 |
--------------------------------------------------------
したがって、[0,1] の範囲で作業する場合、一部の数値は倍精度で正確に表現できないことがわかります。そのため、[0.2, 0.4] の中間にあるはずの 0.3 は、丸め誤差のために 0.4 よりも下端の 0.2 に近くなります。反対側では、2.5 は [2,3] (すべての数値が正確に表されている) のちょうど真ん中にあり、最近傍を使用して上端 3 に割り当てられます。
また、 と が異なる出力を生成する場合があることにも注意してcolon
くださいlinspace
。
>> (0:0.1:1)' - linspace(0,1,11)'
ans =
0
0
0
5.5511e-17
0
0
0
0
0
0
0