Main Content

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

コード生成における cell 配列の制限事項

コード生成用の MATLAB® コードで cell 配列を使用するときは、以下の制限に従わなければなりません。

cell 配列要素の代入

cell 配列要素は、使用する前にすべての実行パスに代入しなければなりません。以下に例を示します。

function z = foo(n)
%#codegen
c = cell(1,3);
if n < 1
    c{2} = 1;
    
else
    c{2} = n;
end
z = c{2};
end

コード ジェネレーターでは、cell 配列を関数に渡したり関数から返したりすることを、cell 配列のすべての要素の使用とみなします。したがって、cell 配列を関数に渡すか関数から返す前に、そのすべての要素を代入しなければなりません。たとえば、次のコードは値を c{2} に代入せず、c は関数出力であるため、許可されません。

function c = foo()
%#codegen
c = cell(1,3);
c{1} = 1;
c{3} = 3;
end

要素への値の代入はすべての実行パスで一貫していなければなりません。y{2} はある実行パスでは double、別の実行パスでは char であるため、次のコードは許可されません。

function y = foo(n)
y = cell(1,3)
if n > 1;
    y{1} = 1
    y{2} = 2;
    y{3} = 3;
else
    y{1} = 10;
    y{2} = 'a';
    y{3} = 30;
end

可変サイズの cell 配列

  • coder.varsize は異種混合 cell 配列でサポートされません。

  • 関数 cell を使用して固定サイズの cell 配列を定義する場合、coder.varsize を使用して、cell 配列が可変サイズであることを指定することはできません。たとえば、以下のコードでは、x = cell(1,3) により x が固定サイズの 1 行 3 列の cell 配列になるため、コード生成エラーが発生します。

    ...
    x = cell(1,3);           
    coder.varsize('x',[1 5])
    ...

    中かっこを使用して定義した cell 配列と共に coder.varsize を使用できます。以下に例を示します。

    ...
    x = {1 2 3}; 
    coder.varsize('x',[1 5])
    ...

  • 関数 cell を使用して可変サイズの cell 配列を作成するには、以下のコード パターンを使用します。

    function mycell(n)
    %#codegen
    x = cell(1,n);   
    for i = 1:n
        x{i} = i;
    end
    end

    cell を使用した可変サイズの cell 配列の定義を参照してください。

    cell 配列の上限を指定するには、coder.varsize を使用します。

    function mycell(n)
    %#codegen
    x = cell(1,n);   
    for i = 1:n
        x{i} = i;
    coder.varsize('x',[1,20]);
    end
    end

cell を使用した可変サイズの cell 配列の定義

コード生成では、cell 配列要素を使用する前に、値を cell 配列要素に代入しなければなりません。cell を使用して可変サイズの cell 配列 (cell(1,n) など) を作成すると、MATLAB は空の行列を各要素に代入します。ただし、コード生成でそれらの要素は代入されません。コード生成では、cell を使用して可変サイズの cell 配列を作成した後、cell 配列を使用する前に cell 配列のすべての要素を代入しなければなりません。以下に例を示します。

function z = mycell(n, j)
%#codegen
assert(n < 100);
x = cell(1,n);   
for i = 1:n
    x{i} = i;
end
z = x{j};
end

コード ジェネレーターはコードを解析し、cell 配列を最初に使用する前にすべての要素が代入されているかどうかを判別します。コード ジェネレーターが一部の要素が代入されていないことを検出した場合、コード生成はエラー メッセージを表示して失敗します。たとえば、for ループの上限を j に変更します。

function z = mycell(n, j)
%#codegen
assert(n < 100);
x = cell(1,n);   
for i = 1:j %<- Modified here
    x{i} = i;
end
z = x{j};
end

この変更と n 未満の入力 j によって、この関数では値がすべての cell 配列要素に代入されません。コード生成で次のエラーが発生します。

この行の前に 'x{:}' の各要素が代入されることを
判別できません。

cell 配列のすべての要素がコードで代入されている場合でも、解析ではすべての要素が代入されたことが検出されないため、コード ジェネレーターはこのメッセージを報告します。cell 配列のすべての要素が代入されるか判別できないを参照してください。

このエラーを回避するには、次のガイドラインに従います。

  • cell を使用して可変サイズの cell 配列を定義する場合、次のパターンに従ってコードを記述します。

    function z = mycell(n, j)
    %#codegen
    assert(n < 100);
    x = cell(1,n);   
    for i = 1:n
        x{i} = i;
    end
    z = x{j};
    end
    

    多次元 cell 配列のパターンは次のとおりです。

    function z = mycell(m,n,p)
    %#codegen
    assert(m < 100);
    assert(n < 100);
    assert(p < 100);
    x = cell(m,n,p);
    for i = 1:m
        for j =1:n
            for k = 1:p
                x{i,j,k} = i+j+k;
            end
        end
    end
    z = x{m,n,p};
    end

  • ループ カウンターを 1 ずつインクリメントまたはデクリメントします。

  • 1 つのループ内または 1 セットの入れ子ループで cell 配列を定義します。たとえば、次のコードは許可されません。

    function z = mycell(n, j)
    assert(n < 50);
    assert(j < 50);
    x = cell(1,n);
    for i = 1:5
        x{i} = 5;
    end
    for i = 6:n
        x{i} = 5;
    end
    z = x{j};
    end            

  • セルの次元およびループの初期値と終了値に同じ変数を使用します。たとえば、セルの作成で n を使用し、ループの終了値で m を使用するため、次のコードのコード生成は失敗します。

    function z = mycell(n, j)
    assert(n < 50);
    assert(j < 50);
    x = cell(1,n);
    m = n;
    for i = 1:m
        x{i} = 2;
    end
    z = x{j};
    end               

    セルの作成とループの終了値で n を使用するようにコードを書き換えます。

    function z = mycell(n, j)
    assert(n < 50);
    assert(j < 50);
    x = cell(1,n);
    for i = 1:n
        x{i} = 2;
    end
    z = x{j};
    end

  • 次のパターンで cell 配列を作成します。

    x = cell(1,n)

    必要な cell で一時変数を初期化して、cell 配列を構造体のフィールドまたはオブジェクトのプロパティに代入します。たとえば、次のようにします。

    t = cell(1,n)
    for i = 1:n
        t{i} = i+1;
    end
    myObj.prop = t;
    cell 配列を構造体のフィールドまたはオブジェクトのプロパティに直接代入しないでください。たとえば、次のコードは許可されません。

    myObj.prop = cell(1,n);
    for i = 1:n
        myObj.prop{i} = i+1;
    end

    関数 cell を cell 配列コンストラクター {} 内で使用しないでください。たとえば、次のコードは許可されません。

    x = {cell(1,n)};

  • cell 配列の作成と、cell 配列要素に値を代入するループは一意の実行パスで一緒にしなければなりません。たとえば、次のコードは許可されません。

    function z = mycell(n)
    assert(n < 100);
    if n > 3
        c = cell(1,n);
    else
        c = cell(n,1);
    end
    for i = 1:n
        c{i} = i;
    end
    z = c{n};
    end

    このコードを修正するには、cell 配列を作成するコード ブロックに代入のループを移動します。

    function z = cellerr(n)
    assert(n < 100);
    if n > 3
        c = cell( 1,n);
        for i = 1:n
            c{i} = i;
        end
    else
        c = cell(n,1);
        for i = 1:n
            c{i} = i;
        end
    end
    z = c{n};
    end

cell 配列のインデックス付け

  • 小かっこ () を使用して cell 配列にインデックスを付けることはできません。中かっこ {} を使用して cell 配列にインデックスを付け、セルの内容にアクセスすることを検討してください。

  • 定数のインデックスまたは定数境界をもつ for ループを使用して、異種混合 cell 配列にインデックスを付けなければなりません。

    たとえば、次のコードは許可されません。

    x = {1, 'mytext'};
    disp(x{randi});

    コード ジェネレーターによってループが展開されるため、定数境界をもつ for ループで異種混合 cell 配列にインデックスを付けることができます。展開することによりループの反復ごとにループ本体のコピーが個別に作成されるため、ループ反復の定数にインデックスが作成されます。ただし、for ループ本体が大きい場合や、反復数が多い場合、展開によってコンパイル時間が増加し、非効率的なコードが生成される可能性があります。

    AB が定数の場合、次のコードは、定数境界をもつ for ループで異種混合 cell 配列にインデックスを付ける方法を示します。

    x = {1, 'mytext'};
    for i = A:B
    	 disp(x{i});
    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
    ...

cell 配列の内容

cell 配列に mxarrays を含めることはできません。cell 配列では、外部関数から返される値は格納できません。

外部 C/C++ 関数への cell 配列の受け渡し

cell 配列を coder.ceval に渡すことはできません。変数が coder.ceval への入力引数の場合、cell 配列としてではなく配列または構造体として変数を定義します。

MATLAB Function ブロックでの使用

cell 配列は Simulink® 信号、パラメーター、データ ストア メモリでは使用できません。

関連するトピック