# Code Generation for Probability Distribution Objects

This example shows how to generate code that fits a probability distribution to sample data and evaluates the fitted distribution.

First, define an entry-point function that uses `fitdist` to create a probability distribution object and uses its object functions to evaluate the fitted distribution. Then, generate code for the entry-point function by using `codegen` (MATLAB Coder). An entry-point function can have a probability distribution object as both an input argument and an output argument. Therefore, alternatively, you can define two entry-point functions, one for fitting a distribution and the other for evaluating the fitted distribution. The first entry-point function returns a fitted distribution, and the second entry-point function accepts the fitted distribution as an input argument. This example first describes the workflow with a single entry-point function, and then briefly describes the workflow with two entry-point functions.

`fitdist` supports code generation for beta, exponential, extreme value, lognormal, normal, and Weibull distributions. The supported object functions of the fitted probability distribution objects, created by `fitdist`, are `cdf`, `icdf`, `iqr`, `mean`, `median`, `pdf`, `std`, `truncate`, and `var`.

### Define Entry-Point Function

Define an entry-point function named `myFitandEvaluate` that takes the sample data, distribution name, truncation limits of the distribution, and data values at which to evaluate the cumulative distribution function (cdf) and probability density function (pdf). Within the entry-point function, fit a probability distribution object to the sample data, truncate the distribution to the specified truncation limits, compute the mean of the truncated distribution, and compute the cdf and pdf values at the specified data values.

Display the contents of the `myFitandEvaluate.m` file.

`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 ```

Note: If you click the button located in the upper-right section of this page and open this example in MATLAB®, then MATLAB opens the example folder. This folder includes the entry-point function files for this example.

### Generate Code

Specify the input argument types of `myFitandEvaluate` using a 4-by-1 cell array. Assign each input argument type of the entry-point function to each cell. Specify the data type and exact input array size by using an example value that represents the set of values with a certain data type and array size.

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

The second input of `myFitandEvaluate` is a distribution name, which is the second input argument of `fitdist`. This argument must be a compile-time constant. Therefore, you specify `ARGS{2}` by using `coder.Constant` (MATLAB Coder).

If you want to specify `ARGS{1}` and `ARGS{3}` as variable-size inputs, use `coder.typeof` (MATLAB Coder). For details, see General Code Generation Workflow.

Generate a MEX function from the entry-point function `myFitandEvaluate`. Specify the input argument types using the `-args` option and the cell array `ARGS`.

`codegen myFitandEvaluate -args ARGS`

`codegen` (MATLAB Coder) generates the MEX function `myFitandEvaluate_mex` with a platform-dependent extension in your current folder.

### Verify Generated Code

Pass some data to verify whether `myFitandEvaluate` and `myFitandEvaluate_mex` return the same outputs.

```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);```

Compare the probability distribution objects `pd_truncated` and `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` returns logical 1 (`true`), which means `pd_truncated` and `pd_truncated_mex` are equal.

Compare the structure arrays that contain the mean, cdf, and pdf values.

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

The comparison confirms that `myFitandEvaluate` and `myFitandEvaluate_mex` return the same outputs. The generated code might not produce the same floating-point numerical results as MATLAB, as described in Differences Between Generated Code and MATLAB Code (MATLAB Coder). In that case, compare the values allowing a small tolerance.

### Workflow with Two Entry-Point Functions

An entry-point function can have a probability distribution object as both an input argument and an output argument. Therefore, you can define two entry-point functions, one for fitting a distribution and the other for evaluating the fitted distribution. Then generate code for the two entry-point functions.

#### Define Entry-Point Functions

Define two entry-point functions. The first entry-point function `myFitDist` fits a probability distribution object to the sample data. The second entry-point function `myEvaluateDist` truncates the distribution, computes the mean of the truncated distribution, and computes the cdf and pdf values at the specified data values. `myEvaluateDist` takes the output of `myFitDist` as an input argument.

Display the contents of the `myFitDist.m` and `myEvaluateDist.m` files.

`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 ```

#### Generate Code

Specify the input argument types of `myFitDist` and `myEvaluateDist`.

```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);```

If you do not need to generate a MEX function, then you can specify `ARGS_myEvaluateDist{1}` as `coder.OutputType('myFitdist')`, as described in Pass an Entry-Point Function Output as an Input (MATLAB Coder). You cannot use `coder.OutputType` (MATLAB Coder) when generating a MEX function, because the data type of the output from `myFitDist` does not match the data type of the input to `myEvaluateDist` in the generated MEX function.

Generate code for the two entry-point functions.

`codegen -o myFitandEvaluate_mex2 myFitDist -args ARGS_myFitDist myEvaluateDist -args ARGS_myEvaluateDist`

`codegen` (MATLAB Coder) generates the MEX function `myFitandEvaluate_mex2`. For details about generating code for multiple entry-point functions, see Generate Code for Multiple Entry-Point Functions (MATLAB Coder).

#### Verify Generated Code

Verify the generated code.

```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` returns logical 1 (`true`), which means that the entry-point functions and the corresponding MEX functions return the same outputs.