メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

エラーの解決: 左辺は固定サイズだが右辺は可変サイズ

問題

コード生成では、変数は固定サイズまたは可変サイズのいずれかです。コード ジェネレーターで変数のサイズが変更されていないことを確認できる場合、生成されたコード内の変数のサイズは固定されます。それ以外の場合は、変数のサイズ変更が許可されます。コード ジェネレーターで以前に固定サイズとして定義された変数に可変サイズの値を代入すると、コード ジェネレーターで次のいずれかのエラーが発生します。

この代入は実行できません。次元 dimension は、左辺が固定サイズであるにもかかわらず、右辺が可変サイズであるためです。

この代入は実行できません。要素 'element' の次元 dimension は、左辺が固定サイズであるにもかかわらず、右辺が可変サイズであるためです。

この代入は実行できません。フィールド 'field' の次元 dimension は、左辺が固定サイズであるにもかかわらず、右辺が可変サイズであるためです。

考えられる解決策

このエラーを解決するには、次のいずれかの解決策を試してください。

明示的なインデックスを使用して変数を強制的に同じサイズにする

右辺の変数を可変サイズにする必要がない場合は、明示的なインデックスを使用して変数を強制的に固定サイズにすることができます。たとえば、変数 A および B を定義する関数があるとします。A は可変サイズのスカラーで、B は固定サイズのスカラーです。関数は可変サイズの変数 A を固定サイズの変数 B に代入しようとするため、コード生成は失敗します。

function out = varsizeError2(n) %#codegen
coder.varsize("A",[1 1],[true true]);
A = ones(n,n);
B = 3;
numel(B);
if (n == 3)
    B = A;
end
out = B;
end

この関数のコードを生成するには、明示的なインデックスを使用して A を強制的に固定サイズのスカラーにします。

function out = varsizeExample2(n) %#codegen
coder.varsize("A",[1 1],[true true]);
A = ones(n,n);
B = 3;
numel(B);
if (n == 3)
    B = A(1);
end
out = B;
end

coder.varsize を使用して左辺の変数を可変にする

coder.varsize (MATLAB Coder) を使用して、代入の左辺の変数を可変サイズとして扱うようにコード ジェネレーターに指示します。たとえば、以下の関数を考えます。

function out = varsizeError1(n) %#codegen
A = ones(n,n);
B = magic(3);
numel(B);
if (n == 3)
    B = A;
end
out = B;
end

A のサイズは入力値によって異なるため、コード ジェネレーターは配列 A を可変サイズとして認識します。コードで Bnumel 関数に渡して使用する際、この配列のサイズは定数であるため、コード ジェネレーターは B を固定サイズとして識別します。A は可変サイズで B は固定サイズであるため、代入 B = A のコード生成は失敗します。このエラーを解決するには、coder.varsize を使用して、B のサイズ変更を許可するようにコード ジェネレーターに指示します。

function out = varsizeExample1(n) %#codegen
A = ones(n,n);
B = magic(3);
coder.varsize("B");
numel(B);
if (n == 3)
    B = A;
end
out = B;
end

暗黙的な拡張を回避する

サイズが異なるが互換性のある配列で二項演算を実行すると、コード ジェネレーターは配列を暗黙的に拡張して同じサイズにします。暗黙的に拡張される二項演算または二項関数の出力を異なるサイズの固定サイズ変数に代入すると、コード ジェネレーターでエラーが発生することがあります。たとえば、以下の関数を考えます。

function out = varsizeError3(n) %#codegen
A = ones(n,1);
B = ones(n,n);
if n == 1
    A = A+B;
end
out = A;
end

配列 A の 2 番目の次元は固定サイズです。演算 A+B を実行するために、コード ジェネレーターは A の 2 番目の次元を、B の 2 番目の次元と一致するように暗黙的に拡張します。A+B の結果は、両方の次元で可変サイズである配列です。コード ジェネレーターは、2 番目の次元が可変サイズである変数を 2 番目の次元が固定サイズである変数に代入できないため、コード生成は失敗します。この例では、演算 A+B は両方の配列が 1 行 1 列である場合にのみ実行されます。そのため、coder.noImplicitExpansionInFunction (MATLAB Coder) を使用してこの関数に対する暗黙的な拡張を無効にするか、coder.sameSizeBinaryOp (MATLAB Coder) を使用してこの演算に対する暗黙的な拡張を無効にします。以下に例を示します。

function out = varsizeExample3(n) %#codegen
coder.noImplicitExpansionInFunction
A = ones(n,1);
B = ones(n,n);
if n == 1
    A = A+B;
end
out = A;
end

参考

(MATLAB Coder) | (MATLAB Coder) | (MATLAB Coder)

トピック