メインコンテンツ

coder.varsize

サイズ非互換性エラーを解決して上限を宣言

説明

coder.varsize(varName1,...,varNameN) は、実行時に変数 varName1,...,varNameN の次元のサイズ変更を許可するようにコード ジェネレーターに指示します。それぞれの配列の各次元について、コード ジェネレーターで上限の判別が試行されます。サイズが 1 の次元 ("大きさが 1 の次元") は固定サイズのままになります。大きさが 1 の次元のサイズ変更を許可するようにコード ジェネレーターに指示するには、upperBounds 引数と variableSize 引数を使用して可変サイズの上限を指定する必要があります。コード生成用に MATLAB® コードで可変サイズのデータを定義する方法について詳しくは、コード生成のための可変サイズ データの定義を参照してください。

coder.varsize(varName1,...,varNameN,upperBounds) は、変数 varName1,...,varNameN の各次元の上限を指定します。大きさが 1 の次元は固定サイズのままになります。

coder.varsize(varName1,...,varNameN,upperBounds,variableSize) は、upperBounds で指定された各上限について、その上限が固定サイズか可変サイズかを指定します。大きさが 1 の次元のサイズ変更を許可するようにコード ジェネレーターに指示するには、可変サイズの上限を明示的に指定します。

すべて折りたたむ

変数のサイズが変更されたことをコード ジェネレーターで認識できない場合、サイズ非互換性エラーが生成されることがあります。このようなタイプのエラーを解決するには、coder.varsize を使用して変数のサイズが可変であることを指定します。

たとえば、次の関数は、変数 x を 3 行 3 列の配列として定義し、x を別の関数に渡して使用してから、実行時の入力に応じて x のサイズを変更します。

function out = changeSizeAfterUse(n) %#codegen
x = zeros(3,3);
numel(x); % use x by passing it to another function
if n < 10
    x = zeros(4,4); % change size of x depending on run-time input
end
out = x;
end

この関数のコードを生成すると、コード ジェネレーターでサイズ非互換性エラーが生成されます。このエラーを解決するには、変数を定義した後、それを使用する前に coder.varsize 命令を追加します。

function out = changeSizeAfterUse(n) %#codegen
x = zeros(3,3);
coder.varsize("x");
numel(x); % use x by passing it to another function
if n < 10
    x = zeros(4,4); % change size of x depending on run-time input
end
out = x;
end

コード ジェネレーターでは、加算や乗算などの二項 (2 配列) 演算の実行時にもサイズ非互換性エラーが生成されることがあります。エラーの解決: 配列のサイズに互換性がない (MATLAB Coder)を参照してください。

A をスカラーとして定義し、その後 coder.varsize を使用して、A が最大長 20 の可変サイズの行ベクトルであることを指定する関数を作成します。この関数のコードを生成し、コード生成レポートを調べます。A1x:20 の配列として定義されます。variableSize 引数を指定しない場合、大きさが 1 でない次元は可変サイズとして定義され、大きさが 1 の次元は固定サイズのままになります。

function varSizeUpperBounds() %#codegen
A = 0;
coder.varsize("A",[1 20]);
end

A を 1×1×1 の配列として定義し、その後、coder.varsize を使用して、A の 1 番目の次元が最大サイズ 1 の可変サイズであり、2 番目の次元が固定サイズ 3 であり、3 番目の次元が最大サイズ 20 の可変サイズであることを指定する関数を作成します。この関数のコードを生成し、コード生成レポートを調べます。A:1x3x:20 の配列として定義されます。upperbound 引数と variableSize 引数を使用して可変サイズの上限を明示的に指定したため、コード ジェネレーターは大きさが 1 の次元を可変サイズとして定義します。

function fcn2() %#codegen
A = [0 0 0];
coder.varsize("A",[1 3 20],[true false true]);
end

coder.varsize を使用すると、構造体フィールドのサイズ変更を許可するようにコード ジェネレーターに指示できます。

たとえば、observations1observations2values のフィールドをもつ構造体を定義する関数を作成します。coder.varsize を使用して、observations1observations2 の 1 番目の次元は固定サイズ、2 番目の次元は制限なしとして定義します。coder.varsize を再度使用して、values を最大長 10 の可変サイズの行ベクトルとして定義します。この関数のコードを生成し、コード生成レポートを調べます。コード ジェネレーターは observation1observations2 の制限なしの次元の最大サイズを判別できます。コード ジェネレーターは、observations1observations2values を、それぞれサイズが 2x:102x:151x:10 の配列として定義します。

function out = varSizeFields(n) %#codegen
s = struct("observations1",zeros(2,2),"observations2",zeros(2,2), ...
    "values",zeros(1,1));
coder.varsize("s.observations1","s.observations2",[2 Inf],[false true]);
coder.varsize("s.values",[1 10]);
if n <= 10
    s.observations1 = [1:n;rand(1,n)];
    s.values = randi(100,1,n);
end
if n > 0
    s.observations2 = [1:15;zeros(1,15)];
end
out = s;
end

coder.varsize 命令は、すべての cell 配列要素または特定の cell 配列要素に適用できます。

たとえば、1 行 3 列の cell 配列を 2 つ定義し、各配列に 1 行 2 列の double 型の配列を 3 つ含める関数を作成します。coder.varsize を使用して、cell 配列 ca1 のすべての要素が最大長 5 の可変サイズの行ベクトルであることを指定します。coder.varsize 命令を再度使用して、ca2 の 2 番目の要素が可変サイズの行列であり、両方の次元の最大サイズが 2 であることを指定します。この関数のコードを生成し、コード生成レポートを調べます。ca1 の要素は、可変サイズの 1x:5 の配列として定義されます。ca2 の最初と 3 番目の要素は固定サイズの 1x2 の配列として定義され、2 番目の要素は可変サイズの :2x:2 の行列として定義されます。

function varSizeElement %#codegen
ca1 = {[1 2] [3 4] [5 6]};
ca2 = {[1 2] [3 4] [5 6]};
coder.varsize("ca1{:}",[1 5]);
coder.varsize("ca2{2}",[2 2]);
ca1{1} = 1;
ca1{2} = 1:5;
ca1{3} = 1:3;
ca2{1} = [5 6];
ca2{2} = [1 2;3 4];
ca2{3} = [7 8];
end

coder.varsize を使用して変数の上限を設定し、変数のサイズが実行時の入力に依存している場合、実行時の入力が上限を超えると、実行時のオーバーフロー エラーが発生することがあります。

たとえば、coder.varsize を使用して変数 x を可変サイズの 2 次元配列として宣言し、各次元の上限を 5 に設定する関数を作成します。

function out = boundedVarSize1(n) %#codegen
x = zeros(3,3);
coder.varsize("x",[5 5])
x = zeros(n,n);
out = x;
end

コマンド ラインでこの関数の MEX コードを生成し、コード生成レポートを調べます。コード ジェネレーターは、x:5x:5 の配列として定義します。

codegen boundedVarSize -args {0} -report
Code generation successful: View report

生成された MEX 関数に 5 より大きい値を渡すと、サイズ オーバーフロー エラーが発生します。オーバーフロー エラーを回避するには、実行時の入力が coder.varsize で定義された上限を超えないようにしてください。あるいは、MATLAB コードを書き換えて、実行時のサイズ オーバーフローを防止します。

function out = boundedVarSize2(n) %#codegen
x = zeros(3,3);
coder.varsize("x",[5 5])
if n <= 5
    x = zeros(n,n);
else
    x = zeros(5,5);
end
out = x;
end

入力引数

すべて折りたたむ

可変サイズとして宣言する変数の名前。文字ベクトルまたは string スカラーのコンマ区切りリストとして指定します。変数は、string、入力引数、グローバル変数、MATLAB クラス、または MATLAB クラスのプロパティにすることはできません。

例: coder.varsize("x","y")

配列の各次元の上限。double のベクトルとして指定します。上限は整数または Inf でなければなりません。上限は coder.varsize に渡されるすべての変数に適用されます。上限として渡された整数は、コード生成時に定数でなければなりません。varName1,...,varNameN の各次元の上限を指定する必要があります。上限なしで変数を指定するには、Inf を使用します。

例: coder.varsize("x","y",[5 Inf])

各上限が可変サイズかどうか。logical 値のベクトルとして指定します。上限は upperBounds 入力引数を使用して指定します。variableSize ベクトルは upperBounds ベクトルと同じ長さでなければなりません。

例: coder.varsize("x","y",[10 10 10], [false true true])

制限

  • コード生成では、グローバル変数、MATLAB クラス、および MATLAB クラスのプロパティでの coder.varsize の使用はサポートされていません。

  • コード生成では、string での coder.varsize の使用はサポートされていません。エラーの解決: string でサポートされない coder.varsize (MATLAB Coder)を参照してください。

  • coder.varsize 命令により、コード ジェネレーターは変数のサイズが変化することを可能にするよう指示を受けます。これは変数のサイズを変更しません。たとえば、以下のコードの抜粋について考えます。

    ...
    x = 7;
    coder.varsize("x", [1 5]);
    disp(size(x));
    ...

    coder.varsize 命令の後、x はまだ 1 行 1 列の配列です。x の現在のサイズを超えて要素に値を代入することはできません。たとえば、このコードは、インデックスの 3 が x の次元を超えるため、実行時エラーとなります。

    ...
    x = 7;
    coder.varsize("x", [1,5]);
    x(3) = 1;
    ...

  • coder.varsize を関数の入力引数で呼び出すことはできません。代わりに、次のようにします。

    • 関数がエントリポイント関数である場合、コマンド ラインで coder.typeof を使用して、入力引数が可変サイズであることを指定します。または、MATLAB Coder™ アプリの [入力の型を定義] ステップを使用して、エントリポイント関数の入力引数が可変サイズであることを指定します。

    • 関数がエントリポイント関数ではない場合、呼び出し元の関数で、呼び出される関数への入力となる変数について coder.varsize を使用します。

  • スパース行列の場合、coder.varsize は可変サイズの次元を制限なしとして扱います。

  • cell 配列で coder.varsize を使用するには、cell 配列は同種でなければなりません。コード生成における cell 配列の制限事項を参照してください。

ヒント

  • 多くの場合、コード ジェネレーターは、変数のサイズが実行時に変更される可能性があることを判別できます。その場合、coder.varsize 命令を使用する必要はありません。coder.varize は、コード ジェネレーターでサイズ オーバーフロー エラーが生成される場合、または上限を指定する場合にのみ使用してください。

  • 可変サイズの出力変数を MATLAB Function ブロックで宣言するには、[シンボル] ペインおよびプロパティ インスペクターを使用します。coder.varsize 宣言で上限を指定する場合、その上限はプロパティ インスペクターの上限と一致しなければなりません。可変サイズの MATLAB Function ブロック変数の宣言を参照してください。

  • coder.varsize 宣言で上限を指定せず、コード ジェネレーターが上限を推論できない場合、生成されたコードでは動的メモリ割り当てが使用されます。動的メモリ割り当ては生成されたコードの速度を低下させる可能性があります。場合によっては、upperBounds 引数を使用して上限を指定することで、動的メモリ割り当てを回避できます。

  • coder.varsize を使用して次元の上限が 1 であると指定すると、既定では、次元は固定サイズ 1 になります。次元が 0 または 1 になりうることを指定するには、variableSize ベクトルの対応する要素を true に設定します。たとえば、次の命令は、x の最初の次元が固定サイズの 1 で、他の次元が可変サイズの 5 であることを指定します。

    coder.varsize('x',[1 5 5])

    対照的に、次のコードは、x の最初の次元が上限 1 の可変サイズであることを指定します。

    coder.varsize("x",[1 5 5],[true true true])

  • 外部関数の出力を使用する場合、コード ジェネレーターはコード生成時にその出力のサイズを決定できません。coder.varsize を使用して、その出力の保存に使用する変数を可変サイズとして扱うようにコード ジェネレーターに指示してください。外部関数の可変サイズの出力を実行時に使用を参照してください。

  • 特定の状況下では、coder.varsize を使用して cell 配列を強制的に同種にすることができます。cell 配列を可変サイズにするかの制御を参照してください。

バージョン履歴

R2011a で導入