Main Content

確率分布オブジェクトのコードの生成

この例では、確率分布を標本データに当てはめて、近似分布を評価するコードを生成する方法を示します。

最初に、fitdistを使用して確率分布オブジェクトを作成し、そのオブジェクト関数を使用して近似分布を評価するエントリポイント関数を定義します。次に、codegen (MATLAB Coder)を使用してエントリポイント関数のコードを生成します。エントリポイント関数には入力引数および出力引数の両方として確率分布オブジェクトを含めることができます。そのため、代わりに、分布の近似用と近似分布の評価用に 2 つのエントリポイント関数を定義できます。最初のエントリポイント関数は近似分布を返し、2 番目のエントリポイント関数は近似分布を入力引数として受け入れます。この例では、最初に 1 つのエントリポイント関数を使用するワークフローを説明し、次に 2 つのエントリポイント関数を使用するワークフローを簡単に説明します。

fitdist は、ベータ分布、指数分布、極値分布、対数正規分布、正規分布およびワイブル分布のコード生成をサポートします。fitdist で作成された近似確率分布オブジェクトのサポートされているオブジェクト関数は、cdficdfiqrmeanmedianpdfstdtruncate、およびvarです。

コード生成の詳細については、一般的なコード生成のワークフローを参照してください。

エントリポイント関数の定義

標本データ、分布名、分布の打ち切り制限、累積分布関数 (cdf) と確率密度関数 (pdf) を評価するデータ値をとる myFitandEvaluate という名前のエントリポイント関数を定義します。エントリポイント関数内で確率分布オブジェクトを標本データに当てはめ、指定した打ち切り制限で分布を打ち切り、打ち切られた分布の平均値を計算し、指定したデータ値で cdf 値と pdf 値を計算します。

myFitandEvaluate.m ファイルの内容を表示します。

type myFitandEvaluate.m
function [pd_truncated,st] = myFitandEvaluate(data,distname,truncation_limits,x) %#codegen
% Fit a probability distribution object to data.
pd = fitdist(data,distname);

% Truncate pd.
pd_truncated = truncate(pd,truncation_limits(1),truncation_limits(2));

% Compute the mean of the truncated pd.
mean_val = mean(pd_truncated);

% Compute the cdf and pdf, evaluated at x.
cdf_val = cdf(pd_truncated,x);
pdf_val = pdf(pd_truncated,x);

% Create a structure array containing the mean, cdf, and pdf values.
st = struct('mean', mean_val,'cdf',cdf_val,'pdf',pdf_val);
end

メモ: このページの右上にあるボタンをクリックしてこの例を MATLAB® で開くと、MATLAB で例のフォルダーが開きます。このフォルダーには、この例のエントリポイント関数のファイルが含まれています。

コードの生成

4 行 1 列の cell 配列を使用して myFitandEvaluate の入力引数の型を指定します。エントリポイント関数の各入力引数の型を各 cell に割り当てます。特定のデータ型および配列サイズをもつ一連の値を表す例の値を使用して、データ型と正確な入力配列のサイズを指定します。

ARGS = cell(4,1);
ARGS{1} = ones(100,1);
ARGS{2} = coder.Constant('Exponential');
ARGS{3} = ones(1,2);
ARGS{4} = ones(10,1);

myFitandEvaluate の 2 番目の入力は、分布名です。これは fitdist の 2 番目の入力引数です。この引数はコンパイル時の定数でなければなりません。したがって、coder.Constant (MATLAB Coder)を使用して ARGS{2} を指定します。

ARGS{1} および ARGS{3} を可変サイズの入力として指定する場合は、coder.typeof (MATLAB Coder)を使用します。詳細については、一般的なコード生成のワークフローを参照してください。

エントリポイント関数 myFitandEvaluate から MEX 関数を生成します。-args オプションおよび cell 配列 ARGS を使用して、入力引数の型を指定します。

codegen myFitandEvaluate -args ARGS
Code generation successful.

codegen (MATLAB Coder)は、プラットフォームに依存する拡張子の MEX 関数 myFitandEvaluate_mex を現在のフォルダーに生成します。

生成されたコードの確認

データを渡して、myFitandEvaluate および myFitandEvaluate_mex が同じ出力を返すかどうかを確認します。

rng('default') % For reproducibility
data = exprnd(1,[100,1]); % Exponential random numbers with mean parameter 1
distname = 'Exponential';
truncation_limits = [0,4];
x = (0:9)';
[pd_truncated,st] = myFitandEvaluate(data,distname,truncation_limits,x);
[pd_truncated_mex,st_mex] = myFitandEvaluate_mex(data,distname,truncation_limits,x);

確率分布オブジェクト pd_truncated および pd_truncated_mex を比較します。

pd_truncated
pd_truncated = 
  ExponentialDistribution

  Exponential distribution
    mu = 0.917049
  Truncated to the interval [0, 4]

pd_truncated_mex
pd_truncated_mex = 
  ExponentialDistribution

  Exponential distribution
    mu = 0.917049
  Truncated to the interval [0, 4]

verifyMEX_pd = isequal(pd_truncated,pd_truncated_mex)
verifyMEX_pd = logical
   1

isequalは、logical 1 (true) を返します。これは pd_truncatedpd_truncated_mex が等しいことを意味します。

平均値、cdf 値、および pdf 値が含まれる構造体配列を比較します。

verifyMEX_st = isequal(st,st_mex)
verifyMEX_st = logical
   1

この比較により、myFitandEvaluatemyFitandEvaluate_mex が同じ結果を返すことを確認します。生成されたコードは、生成されたコードと MATLAB コードの相違点 (MATLAB Coder)で説明するように、MATLAB と同じ浮動小数点の数値結果を生成しない可能性があります。このような場合は、小さい誤差を許容して値を比較します。

2 つのエントリポイント関数を使用したワークフロー

エントリポイント関数には入力引数および出力引数の両方として確率分布オブジェクトを含めることができます。そのため、分布の近似用と近似分布の評価用に 2 つのエントリポイント関数を定義できます。次に、2 つのエントリポイント関数のコードを生成します。

エントリポイント関数の定義

2 つのエントリポイント関数を定義します。最初のエントリポイント関数 myFitDist は確率分布オブジェクトを標本データに当てはめます。2 番目のエントリポイント関数 myEvaluateDist は分布を打ち切り、打ち切られた分布の平均値を計算し、指定したデータ値で cdf 値と pdf 値を計算します。myEvaluateDistmyFitDist の出力を入力引数としてとります。

myFitDist.m ファイルと myEvaluateDist.m ファイルの内容を表示します。

type myFitDist.m
function pd = myFitDist(data,dist) %#codegen
% Fit probability distribution object to data.
pd = fitdist(data,dist);
end
type myEvaluateDist.m
function [pd_truncated,st] = myEvaluateDist(pd,truncation_limits,x) %#codegen
% Truncate pd.
pd_truncated = truncate(pd,truncation_limits(1),truncation_limits(2));

% Compute the mean of the truncated pd.
mean_val = mean(pd_truncated);

% Compute the cdf and pdf, evaluated at x.
cdf_val = cdf(pd_truncated,x);
pdf_val = pdf(pd_truncated,x);

% Create a structure array containing the mean, cdf, and pdf values.
st = struct('mean', mean_val,'cdf',cdf_val,'pdf',pdf_val);
end

コードの生成

myFitDistmyEvaluateDist の入力引数の型を指定します。

ARGS_myFitDist = cell(2,1);
ARGS_myFitDist{1} = ones(100,1);
ARGS_myFitDist{2} = coder.Constant('Exponential');

ARGS_myEvaluateDist = cell(3,1);
ARGS_myEvaluateDist{1} = fitdist(exprnd(1,[100,1]),'Exponential');
ARGS_myEvaluateDist{2} = ones(1,2); 
ARGS_myEvaluateDist{3} = ones(10,1);

MEX 関数を生成する必要がない場合は、入力としてのエントリポイント関数出力の受け渡し (MATLAB Coder)で説明するように、ARGS_myEvaluateDist{1}coder.OutputType('myFitdist') として指定できます。MEX 関数を生成する場合、coder.OutputType (MATLAB Coder)は使用できません。myFitDist からの出力のデータ型が、生成された MEX 関数の myEvaluateDist への入力のデータ型と一致しないためです。

2 つのエントリポイント関数のコードを生成します。

codegen -o myFitandEvaluate_mex2 myFitDist -args ARGS_myFitDist myEvaluateDist -args ARGS_myEvaluateDist
Code generation successful.

codegen (MATLAB Coder)は MEX 関数 myFitandEvaluate_mex2 を生成します。複数のエントリポイント関数に対するコード生成の詳細については、複数のエントリポイント関数のためのコード生成 (MATLAB Coder)を参照してください。

生成されたコードの確認

生成されたコードを検証します。

rng('default') 
data = exprnd(1,[100,1]);
distname = 'Exponential';
truncation_limits = [0,4];
x = (0:9)';
pd2 = myFitDist(data,distname);
[pd_truncated2,st2] = myEvaluateDist(pd2,truncation_limits,x);
pd_mex2 = myFitandEvaluate_mex2('myFitDist',data,distname);
[pd_truncated_mex2,st_mex2] = myFitandEvaluate_mex2('myEvaluateDist',pd_mex2,truncation_limits,x);
verifyMEX_pd2 = isequal(pd2,pd_mex2)
verifyMEX_pd2 = logical
   1

verifyMEX_pd_truncated2 = isequal(pd_truncated2,pd_truncated_mex)
verifyMEX_pd_truncated2 = logical
   1

verifyMEX_st2 = isequal(st2,st_mex2)
verifyMEX_st2 = logical
   1

isequalは logical 1 (true) を返します。これは、エントリポイント関数と対応する MEX 関数が同じ出力を返すことを意味します。

参考

(MATLAB Coder) | | | | | | |

関連するトピック