Analyzing MATLAB models with pygpc#

You can easily investigate your models written in MATLAB with pygpc. In order to do so, you have to install the MATLAB Engine API for Python.

import matplotlib.pyplot as plt

_ = plt.figure(figsize=[15, 7])
_ = plt.imshow(plt.imread("../images/python_matlab_interface.png"))
_ = plt.axis('off')
plot matlab model

Install MATLAB Engine API for Python#

To start the MATLAB engine within a Python session, you first must install the engine API as a Python package. MATLAB provides a standard Python setup.py file for building and installing the engine using the distutils module. You can use the same setup.py commands to build and install the engine on Windows, Mac, or Linux systems.

Before you install, verify your Python and MATLAB configurations.

  • Check that your system has a supported version of Python and MATLAB R2014b or later. To check that Python is installed on your system, run Python at the operating system prompt.

  • Add the folder that contains the Python interpreter to your path, if it is not already there.

  • Find the path to the MATLAB folder. Start MATLAB and type matlabroot in the command window. Copy the path returned by matlabroot.

To install the engine API, choose one of the following. (You might need administrator privileges to execute these commands.)

Windows

> cd "matlabroot\extern\engines\python"
> python setup.py install

macOS or Linux

> cd "matlabroot/extern/engines/python"
> python setup.py install

Withing MATLAB

cd (fullfile(matlabroot,'extern','engines','python'))
system('python setup.py install')

After you installed the MATLAB Engine API for Python, you can set

options["matlab_model"] = True

in your gPC run-file.

You can find an example model-file in .../templates/MyModel_matlab.py and the associated gPC run-file in .../templates/MyGPC_matlab.py.

For additional readings visit the Calling MATLAB from Python homepage.

Setting up the Matlab model#

Setting up the model in Matlab is straight forward. You simply have to define your model as a matlab function within an .m file. In the following, you see an example model .m file:

% Three-dimensional test function of Ishigami.

function y = Ishigami(x1, x2, x3, a, b)

y = sin(x1) + a .* sin(x2).^2 + b .* x3.^4 .* sin(x1);

Accessing the model within pypgc#

In order to call the Matlab function within pygpc, we have to set up a corresponding python model as shown below. During initialization we pass the function name fname_matlab, which tells pygpc where to find the model .m function. During computation, pygpc creates and passes a matlab_engine instance. Before the model can be called, the input parameters from the parameters dictionary p have to be converted to lists, which can be read by the matlab engine.

The example shown below can be found in the templates folder of pygpc (/templates/MyModel_matlab.py)

import inspect
import numpy as np
import matlab.engine
from pygpc.AbstractModel import AbstractModel


class MyModel_matlab(AbstractModel):
    '''
    MyModel evaluates something using Matlab. The parameters of the model
    (constants and random parameters) are stored in the dictionary p.
    Their type is defined during the problem definition.

    Parameters
    ----------
    fname_matlab : str
        Filename of Matlab function
    p["x1"] : float or ndarray of float [n_grid]
        Parameter 1
    p["x2"] : float or ndarray of float [n_grid]
        Parameter 2
    p["x3"] : float or ndarray of float [n_grid]
        Parameter 3
    p["a"] : float
        shape parameter (a=7)
    p["b"] : float
        shape parameter (b=0.1)

    Returns
    -------
    y : ndarray of float [n_grid x n_out]
        Results of the n_out quantities of interest the gPC is conducted for
    additional_data : dict or list of dict [n_grid]
        Additional data, will be saved under its keys in the .hdf5 file during gPC simulations.
        If multiple grid-points are evaluated in one function call, return a dict for every
        grid-point in a list
    '''

    def __init__(self, fname_matlab):
        super(type(self), self).__init__(matlab_model=True)
        self.fname_matlab = fname_matlab                        # filename of matlab function
        self.fname = inspect.getfile(inspect.currentframe())    # filename of python function

    def validate(self):
        pass

    def simulate(self, matlab_engine, process_id=None):#
        # add path of Matlab function
        matlab_engine.addpath(self.fname_matlab, nargout=0)

        # convert input parameters to matlab format (only lists can be converted)
        x1 = matlab.double(np.array(self.p["x1"]).tolist())
        x2 = matlab.double(np.array(self.p["x2"]).tolist())
        x3 = matlab.double(np.array(self.p["x3"]).tolist())
        a = matlab.double(np.array(self.p["a"]).tolist())
        b = matlab.double(np.array(self.p["b"]).tolist())

        # call Matlab function
        y = matlab_engine.Ishigami(x1, x2, x3, a, b)

        # convert the output back to numpy and ensure that the output is [n_grid x n_out]
        y = np.array(y).transpose()

        if y.ndim == 0:
            y = np.array([[y]])
        elif y.ndim == 1:
            y = y[:, np.newaxis]

        # delete matlab engine after simulations because it can not be saved in the gpc object
        del self.matlab_engine

        return y

Performance Tip#

You can use the parallel computation capabilities of Matlab, i.e. its good handling with arrays and matrices. If your function can process arrays for the input parameters passed in the dictionary p, you can set the algorithm option:

options = dict()

# ...
options["n_cpu"] = 0
# ...

to enable parallel processing in pygpc. In this way, multiple sampling points are passed to the function and processed in parallel, which speeds up your gPC analysis. A more detailed description about the parallel processing capabilities of pygpc is given in this example.

Total running time of the script: ( 0 minutes 0.290 seconds)

Gallery generated by Sphinx-Gallery