Save a dictionary of python types to a MATLAB MAT file.

    Saves the data provided in the dictionary `mdict` to a MATLAB MAT
    file. `format` determines which kind/vesion of file to use. The
    '7.3' version, which is HDF5 based, is handled by this package and
    all types that this package can write are supported. Versions 4 and
    5 are not HDF5 based, so everything is dispatched to the SciPy
    package's ``scipy.io.savemat`` function, which this function is
    modelled after (arguments not specific to this package have the same
    names, etc.).

    Parameters
    ----------
    file_name : str or file-like object
        Name of the MAT file to store in. The '.mat' extension is
        added on automatically if not present if `appendmat` is set to
        ``True``. An open file-like object can be passed if the writing
        is being dispatched to SciPy (`format` < 7.3).
    mdict : dict
        The dictionary of variables and their contents to store in the
        file.
    appendmat : bool, optional
        Whether to append the '.mat' extension to `file_name` if it
        doesn't already end in it or not.
    format : {'4', '5', '7.3'}, optional
        The MATLAB mat file format to use. The '7.3' format is handled
        by this package while the '4' and '5' formats are dispatched to
        SciPy.
    oned_as : {'row', 'column'}, optional
        Whether 1D arrays should be turned into row or column vectors.
    store_python_metadata : bool, optional
        Whether or not to store Python type information. Doing so allows
        most types to be read back perfectly. Only applicable if not
        dispatching to SciPy (`format` >= 7.3).
    action_for_matlab_incompatible: str, optional
        The action to perform writing data that is not MATLAB
        compatible. The actions are to write the data anyways
        ('ignore'), don't write the incompatible data ('discard'), or
        throw a ``TypeNotMatlabCompatibleError`` exception.
    marshaller_collection : MarshallerCollection, optional
        Collection of marshallers to disk to use. Only applicable if
        not dispatching to SciPy (`format` >= 7.3).
    truncate_existing : bool, optional
        Whether to truncate the file if it already exists before writing
        to it.
    truncate_invalid_matlab : bool, optional
        Whether to truncate a file if the file doesn't have the proper
        header (userblock in HDF5 terms) setup for MATLAB metadata to be
        placed.
    **keywords :
        Additional keywords arguments to be passed onto
        ``scipy.io.savemat`` if dispatching to SciPy (`format` < 7.3).

    Raises
    ------
    ImportError
        If `format` < 7.3 and the ``scipy`` module can't be found.
    NotImplementedError
        If writing a variable in `mdict` is not supported.
    exceptions.TypeNotMatlabCompatibleError
        If writing a type not compatible with MATLAB and
        `action_for_matlab_incompatible` is set to ``'error'``.

    Notes
    -----
    Writing the same data and then reading it back from disk using the
    HDF5 based version 7.3 format (the functions in this package) or the
    older format (SciPy functions) can lead to very different
    results. Each package supports a different set of data types and
    converts them to and from the same MATLAB types differently.

    See Also
    --------
    loadmat : Equivelent function to do reading.
    scipy.io.savemat : SciPy function this one models after and
        dispatches to.
    Options
    writes : Function used to do the actual writing.

def savemat(file_name, mdict, appendmat=True, format='7.3',
            oned_as='row', store_python_metadata=True,
            action_for_matlab_incompatible='error',
            marshaller_collection=None, truncate_existing=False,
            truncate_invalid_matlab=False, **keywords):
    """ Save a dictionary of python types to a MATLAB MAT file.

    Saves the data provided in the dictionary `mdict` to a MATLAB MAT
    file. `format` determines which kind/vesion of file to use. The
    '7.3' version, which is HDF5 based, is handled by this package and
    all types that this package can write are supported. Versions 4 and
    5 are not HDF5 based, so everything is dispatched to the SciPy
    package's ``scipy.io.savemat`` function, which this function is
    modelled after (arguments not specific to this package have the same
    names, etc.).

    Parameters
    ----------
    file_name : str or file-like object
        Name of the MAT file to store in. The '.mat' extension is
        added on automatically if not present if `appendmat` is set to
        ``True``. An open file-like object can be passed if the writing
        is being dispatched to SciPy (`format` < 7.3).
    mdict : dict
        The dictionary of variables and their contents to store in the
        file.
    appendmat : bool, optional
        Whether to append the '.mat' extension to `file_name` if it
        doesn't already end in it or not.
    format : {'4', '5', '7.3'}, optional
        The MATLAB mat file format to use. The '7.3' format is handled
        by this package while the '4' and '5' formats are dispatched to
        SciPy.
    oned_as : {'row', 'column'}, optional
        Whether 1D arrays should be turned into row or column vectors.
    store_python_metadata : bool, optional
        Whether or not to store Python type information. Doing so allows
        most types to be read back perfectly. Only applicable if not
        dispatching to SciPy (`format` >= 7.3).
    action_for_matlab_incompatible: str, optional
        The action to perform writing data that is not MATLAB
        compatible. The actions are to write the data anyways
        ('ignore'), don't write the incompatible data ('discard'), or
        throw a ``TypeNotMatlabCompatibleError`` exception.
    marshaller_collection : MarshallerCollection, optional
        Collection of marshallers to disk to use. Only applicable if
        not dispatching to SciPy (`format` >= 7.3).
    truncate_existing : bool, optional
        Whether to truncate the file if it already exists before writing
        to it.
    truncate_invalid_matlab : bool, optional
        Whether to truncate a file if the file doesn't have the proper
        header (userblock in HDF5 terms) setup for MATLAB metadata to be
        placed.
    **keywords :
        Additional keywords arguments to be passed onto
        ``scipy.io.savemat`` if dispatching to SciPy (`format` < 7.3).

    Raises
    ------
    ImportError
        If `format` < 7.3 and the ``scipy`` module can't be found.
    NotImplementedError
        If writing a variable in `mdict` is not supported.
    exceptions.TypeNotMatlabCompatibleError
        If writing a type not compatible with MATLAB and
        `action_for_matlab_incompatible` is set to ``'error'``.

    Notes
    -----
    Writing the same data and then reading it back from disk using the
    HDF5 based version 7.3 format (the functions in this package) or the
    older format (SciPy functions) can lead to very different
    results. Each package supports a different set of data types and
    converts them to and from the same MATLAB types differently.

    See Also
    --------
    loadmat : Equivelent function to do reading.
    scipy.io.savemat : SciPy function this one models after and
        dispatches to.
    Options
    writes : Function used to do the actual writing.

    """
    # If format is a number less than 7.3, the call needs to be
    # dispatched to the scipy version, if it is available, with all the
    # relevant and extra keywords options provided.
    if float(format) < 7.3:
        import scipy.io
        scipy.io.savemat(file_name, mdict, appendmat=appendmat,
                         format=format, oned_as=oned_as, **keywords)
        return

    # Append .mat if it isn't on the end of the file name and we are
    # supposed to.
    if appendmat and not file_name.endswith('.mat'):
        file_name = file_name + '.mat'

    # Make the options with matlab compatibility forced.
    options = Options(store_python_metadata=store_python_metadata, \
        matlab_compatible=True, oned_as=oned_as, \
        action_for_matlab_incompatible=action_for_matlab_incompatible, \
        marshaller_collection=marshaller_collection)

    # Write the variables in the dictionary to file.
    writes(mdict=mdict, filename=file_name,
           truncate_existing=truncate_existing,
           truncate_invalid_matlab=truncate_invalid_matlab,
           options=options)