Main Content

言語制約の回避: コード生成はオブジェクト配列をサポートしていません

問題

MATLAB® アルゴリズムでは、特定の状況において、同じクラスのインスタンスを示すオブジェクトの配列が使用されます。ただし、オブジェクト配列はコード生成でサポートされていません。そのような MATLAB コードのコードを生成しようとすると、次のようなエラー メッセージが表示されます。

コード生成はオブジェクト配列をサポートしていません。

考えられる解決策

オブジェクトの cell 配列を使用する

オブジェクトの cell 配列はコード生成でサポートされています。MATLAB コードで、配列の代わりに cell 配列を使用してオブジェクトのコレクションを表現します。

たとえば、MATLAB アルゴリズムでクラス Square を使用するとします。

classdef Square
    properties(Access = private)
        side
    end

    methods(Access = public)
        function obj = Square(side)
            obj.side = side;
        end

        function area = calculateArea(obj)
            area = obj.side^2;
        end
    end
end

関数 addAreas は、13 列の Square オブジェクトの配列を構成して使用します。

function y = addAreas(n)
obj = Square(0);
collection = [obj obj obj]; % collection is an array

for i = 1:numel(collection)
    collection(i) = Square(n + i);
end

y = 0;
for i = 1:numel(collection)
    y = y + collection(i).calculateArea;
end
end

addAreas の MEX 関数を生成してみます。ローカル変数 collection がオブジェクト配列であるため、コード生成に失敗します。

codegen addAreas -args 0 -report
??? Code generation does not support object arrays.

Error in ==> addAreas Line: 3 Column: 14
Code generation failed: View Error Report

代わりに collection を cell 配列として再定義します。cell 配列インデックスを使用して collection にインデックスを付けるようにコードを変更します。変更した関数に addAreas_new という名前を付けます。

function y = addAreas_new(n)
obj = Square(0);
collection = {obj obj obj}; % collection is a cell array

for i = 1:numel(collection)
    collection{i} = Square(n + i);
end

y = 0;
for i = 1:numel(collection)
    y = y + collection{i}.calculateArea;
end
end

addAreas_new の MEX 関数を生成してみます。コード生成に成功し、addAreas_new_mex が生成されます。

codegen addAreas_new -args 0 -report
Code generation successful: View report

addAreas_newaddAreas_new_mex の実行時の動作が同じになることを確認します。

disp([addAreas_new(0) addAreas_new_mex(0)])
14    14

非スカラー インデックスによる代入には中かっこと deal を使用する

元の MATLAB コードで、非スカラー インデックスを使用してオブジェクトの配列への代入を実行するとします。たとえば、関数 addAreas の最初の for ループの後に次の行を追加します。

collection(1:2) = [Square(10) Square(20)];

変更した関数 addAreas_new で、対応する cell 配列に中かっこ {} を使用してインデックスを付け、関数 deal を使用して代入を実行します。上記の行を次のように置き換えます。

[collection{1:2}] = deal(Square(10),Square(20));

関連するトピック