end + 1
のインデックス付けを使用して配列と cell 配列を拡張するためのコード生成
コード生成では、end + 1
のインデックス付けを使用した MATLAB® コード内の配列または cell 配列の拡張がサポートされます。この機能を使用するには、コード生成構成プロパティ EnableVariableSizing
または MATLAB Coder™ アプリにおける対応する設定 [可変サイズを有効化] が有効になっていることを確認します。
(end + 1)
のインデックス付けを使用した配列の拡張
配列 X
を拡張する場合、値を X(end + 1)
に代入できます。この代入を MATLAB コードで行うと、拡張する次元がコード ジェネレーターで可変サイズとして扱われます。
たとえば、次のコードの抜粋についてのコードを生成できます。
... a = [1 2 3 4 5 6]; a(end + 1) = 7; b = [1 2]; for i = 3:10 b(end + 1) = i; end ...
(end + 1)
を使用して配列を拡張する場合は、次の制限事項を考慮します。
(end + 1)
のみ使用します。(end + 2)
や(end + 3)
などは使用しません。(end + 1)
はベクトルでのみ使用します。たとえば、次のコードはX
が行列であり、ベクトルではないため許可されません。... X = [1 2; 3 4]; X(end + 1) = 5; ...
サイズが
1x0
の空の配列は(end + 1)
を使用して拡張できます。サイズが0x1
の配列の拡張はサポートされていません。サイズが0x0
の配列の拡張は、その配列を[]
を使用して作成する場合のみサポートされます。
実行時にスカラーとして初期化される可変サイズの列配列の拡張
MATLAB の実行で、(end+1)
のインデックス付けを使用してスカラー配列を拡張すると、配列は 2 番目の次元に沿って拡張され、行ベクトルが生成されます。たとえば、以下のような関数 grow
を定義します。
function z = grow(n, m) n(end+1) = m; z = n; end
次のサンプル入力を使用して grow
を呼び出します。
grow(2,3)
ans = 2 3
一方、コード生成では、以下を仮定します。
コンパイル時に配列を可変サイズの列タイプ (
:Inf x 1
など) に指定し、"さらに"実行時にこの配列をスカラーとして初期化する。
このような場合、生成されたコードでは、スカラーの拡張が最初の次元に沿って試行されるため、ランタイム エラーが発生します。たとえば、grow
の MEX コードを生成します。入力 n
を :Inf x 1
の double の配列に指定します。入力 m
を double のスカラーに指定します。
codegen grow -args {coder.typeof(0, [Inf 1], [1 0]), 1}
Code generation successful.
前と同じ入力を使用して、生成された MEX を実行します。
grow_mex(2,3)
Attempted to grow a scalar along the first dimension using end+1 indexing. This behavior differs from MATLAB execution which grows a scalar along the second dimension. Error in grow (line 2) n(end+1) = m;
このエラーを回避する方法. このエラーを回避し、生成されたコードと MATLAB の実行の両方で列の次元に沿って配列を拡張するには、次の "いずれか" の方法で MATLAB コードを書き換えます。
(end+1)
を使用する代わりに、連結演算子を使用して配列を拡張します。たとえば、関数grow
を次のように書き換えます。function z = growCat(n, m) n = [n;m]; z = n; end
関数内で、拡張する変数を転置して一時変数を作成します。次に、
(end+1)
のインデックス付けを使用してこの一時変数を拡張します。最後に、この一時変数の 2 番目の転置を取ります。たとえば、関数grow
を次のように書き換えます。function z = growTransposed(n, m) temp = n'; temp(end+1) = m; z = temp'; end
{end + 1}
のインデックス付けを使用した cell 配列の拡張
cell 配列 X
を拡張するには、X{end + 1}
を使用できます。次に例を示します。
... X = {1 2}; X{end + 1} = 'a'; ...
{end + 1}
を使用して cell 配列を拡張する場合は、次の制限事項を考慮します。
MATLAB Function ブロックでは、
for
ループで{end + 1}
を使用できません。{end + 1}
のみ使用します。{end + 2}
や{end + 3}
などは使用しません。{end + 1}
はベクトルでのみ使用します。たとえば、次のコードはX
が行列であり、ベクトルではないため許可されません。... X = {1 2; 3 4}; X{end + 1} = 5; ...
{end + 1}
を変数でのみ使用します。以下のコードでは、{end + 1}
は{1 2 3}
を拡張しません。この場合、コード ジェネレーターは{end + 1}
をX{2}
への範囲外のインデックスとして扱います。... X = {'a' { 1 2 3 }}; X{2}{end + 1} = 4; ...
{end + 1}
でループ内の cell 配列を拡張する場合、cell 配列は可変サイズでなければなりません。したがって、cell 配列は同種でなければなりません。このコードは
X
が同種であるため許可されます。... X = {1 2}; for i=1:n X{end + 1} = 3; end ...
このコードは
X
が異種混合であるため許可されません。... X = {1 'a' 2 'b'}; for i=1:n X{end + 1} = 3; end ...
生成されたコードと MATLAB における動作の違いの原因となるコーディング パターンについては、実行時にスカラーとして初期化される可変サイズの列 cell 配列の拡張を参照してください。