end + 1 のインデックス付けを使用して配列と cell 配列を拡張するためのコード生成
コード生成では、end + 1 のインデックス付けを使用した MATLAB® コード内の配列または cell 配列の拡張がサポートされます。コード生成では、既定で可変サイズの配列がサポートされます。この機能が有効なことを確認する場合は、構成オブジェクト プロパティ EnableVariableSizing が true に設定されていることを確認します。
(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)
end+1 インデックスを使用して、最初の次元に沿ってスカラーを拡大しようとしました。この動作は、2 番目の次元に沿ってスカラーを拡大する MATLAB の実行とは異なります。
このエラーを回避する方法. このエラーを回避し、生成されたコードと 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 配列の拡張を参照してください。