Main Content

Sum ブロックと MATLAB Function ブロックの加算の数値応答の比較

この例では、シミュレーション入力を生成し、それらを使用してモデルを動作範囲全体にわたって実行する方法を示します。この例では、モデルのシミュレーションを実行するためにテスト データを生成し、Sum ブロックと ex_testsum モデルの MATLAB® Function ブロックに実装されている加算の数値応答を比較します。

モデルを開きます。

model = 'ex_testsum';
open_system(model);

データ属性の指定とデータの生成

fixed.DataSpecification オブジェクトを使用して、入力データ属性を指定します。この例では、2 つの DataSpecification オブジェクトを作成します。そのうちの 1 つでは倍精度データ型を使用し、他方では単精度データ型を使用します。最初のオブジェクトによって生成された値の間隔は 1 から 64 であり、二番目によって生成された値の間隔は 1 から 32 です。

dataspec1 = fixed.DataSpecification('double', 'Intervals', {1 64});
dataspec2 = fixed.DataSpecification('single', 'Intervals', {1 32});

DataGenerator オブジェクトは、数値的に豊富な値の組み合わせを生成します。Simulink® モデルで出力データを使用するには、出力の形式を 'timeseries' に設定します。

datagen = fixed.DataGenerator;
datagen.DataSpecifications = {dataspec1, dataspec2};
[tsdata1, tsdata2] = outputAllData(datagen, 'timeseries');

モデルの設定とシミュレーション

DataSpecification オブジェクトの属性をモデルの Inport ブロックに適用します。

set_param('ex_testsum/In1',...
    'OutDataTypeStr',dataspec1.DataTypeStr,...
    'SignalType',dataspec1.Complexity,...
    'PortDimensions',['[' num2str(dataspec1.Dimensions) ']'])
set_param('ex_testsum/In2',...
    'OutDataTypeStr',dataspec2.DataTypeStr,...
    'SignalType',dataspec2.Complexity,...
    'PortDimensions',['[' num2str(dataspec2.Dimensions) ']'])

生成された timeseries データをモデルに読み込み、シミュレーションを実行します。

set_param(model, 'LoadExternalInput', 'on',...
    'ExternalInput', 'tsdata1, tsdata2',...
    'StopTime', string(tsdata1.Time(end)));

simout = sim(model);

出力の可視化

シミュレーションの出力を可視化し、加算演算の 2 つの実装の数値動作を比較します。

データ セットごとに、生成されたデータの一意の値を取得します。

[x, y] = datagen.getUniqueValues;
d = abs(simout.yout{1}.Values.Data - simout.yout{2}.Values.Data);
X = reshape(tsdata1.Data, numel(x), []);
Y = reshape(tsdata2.Data, numel(x), []);
D = reshape(d, numel(x), []);

出力の差を入力値の関数としてプロットします。

figure;
surf(X, Y, D, 'EdgeColor', 'none');
grid on;
view(2);
axis tight;
xlabel('In1');
ylabel('In2');
colorbar;
title('abs(MATLAB Function block output - Sum block output)');

プロットから、数値入力の値が大きくなると、2 つの実装間の違いも増加することがわかります。この違いは、2 つの実装のアキュムレータのデータ型の違いに起因します。

数値応答と単精度アキュムレータの比較

Sum ブロックの [アキュムレータのデータ型] パラメーターを Inherit: Inherit via internal rule に設定します。この場合、アキュムレータに使用されるデータ型は倍精度浮動小数点型です。[アキュムレータのデータ型]single に設定し、出力を再度比較します。

set_param([model,'/Sum'], 'AccumDataTypeStr', 'single')
simout = sim(model);

出力を可視化します。Sum ブロックのアキュムレータ型を single に設定すると、実装はすべての値で同じ結果を返します。

[x, y] = datagen.getUniqueValues;
d = abs(simout.yout{1}.Values.Data - simout.yout{2}.Values.Data);
X = reshape(tsdata1.Data, numel(x), []);
Y = reshape(tsdata2.Data, numel(x), []);
D = reshape(d, numel(x), []);
figure;
surf(X, Y, D, 'EdgeColor', 'none');
grid on;
view(2);
axis tight;
xlabel('In1');
ylabel('In2');
colorbar;
title('abs(MATLAB Function block output - Sum block output)');