Quick Start
***********

Opening and Creating MAT Files
==============================

This section will show how to create a new MAT file, open an existing MAT file for read and read/write access, and close the MAT file.

The key functions in working with MAT files include:

  * Mat_Open,

  * Mat_CreateVer, and

  * Mat_Close.

The following example program shows how to open a MAT file where the filename is the first argument to the program.
#include <stdlib.h>
#include <stdio.h>
#include "matio.h"

int
main(int argc,char **argv)
{
    mat_t *matfp;

    matfp = Mat_Open(argv[1],MAT_ACC_RDONLY);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error opening MAT file \"%s\"!\n",argv[1]);
        return EXIT_FAILURE;
    }

    Mat_Close(matfp);
    return EXIT_SUCCESS;
}

The Mat_CreateVer creates a new MAT file (or overwrites an existing file) with a specific version. The matio library can write version 4 MAT files, version 5 MAT files, version 5 MAT files with variable compression (if built with zlib), and HDF5 format MAT files introduced in MATLAB version 7.3. The format of the MAT file is specified by the third argument. The short example below creates a version 4 MAT file named matfile4.mat, a version 5 MAT file named matfile5.mat and an HDF5 format MAT file named matfile73.mat.

#include <stdlib.h>
#include <stdio.h>
#include "matio.h"

int
main(int argc,char **argv)
{
    mat_t *matfp;

    matfp = Mat_CreateVer("matfile4.mat",NULL,MAT_FT_MAT4);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error creating MAT file \"matfile4.mat\"!\n");
        return EXIT_FAILURE;
    }
    Mat_Close(matfp);

    matfp = Mat_CreateVer("matfile5.mat",NULL,MAT_FT_MAT5);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error creating MAT file \"matfile5.mat\"!\n");
        return EXIT_FAILURE;
    }
    Mat_Close(matfp);

    matfp = Mat_CreateVer("matfile73.mat",NULL,MAT_FT_MAT73);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error creating MAT file \"matfile73.mat\"!\n");
        return EXIT_FAILURE;
    }
    Mat_Close(matfp);

    return EXIT_SUCCESS;
}

Reading Variables in a MAT File
===============================

This section introduces the functions used to read variables from a MAT file. The matio library has functions for reading variable information only (e.g. name, rank, dimensions, type, etc.), reading information and data, and reading data from previously obtained information. Reading information and data in separate function calls provides several conveniences including:

  * Querying the names of variables in a file without reading data,

  * Reading only some fields of a structure or elements of a cell array, and

  * other actions where the variable data is not needed.

Reading a Variable by Name
--------------------------

If the name of the variable is known, the Mat_VarRead and Mat_VarReadInfo functions can be used. The Mat_VarRead function reads both the information and data for a variable, and the Mat_VarReadInfo reads information only. The short example below reads a named variable from a MAT file, and checks that the variable is a complex double-precision vector.
#include <stdlib.h>
#include <stdio.h>
#include "matio.h"

int
main(int argc,char **argv)
{
    mat_t    *matfp;
    matvar_t *matvar;

    matfp = Mat_Open(argv[1],MAT_ACC_RDONLY);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error opening MAT file \"%s\"!\n",argv[1]);
        return EXIT_FAILURE;
    }

    matvar = Mat_VarReadInfo(matfp,"x");
    if ( NULL == matvar ) {
        fprintf(stderr,"Variable 'x' not found, or error "
                       "reading MAT file\n");
    } else {
        if ( !matvar->isComplex )
            fprintf(stderr,"Variable 'x' is not complex!\n");
        if ( matvar->rank != 2 ||
             (matvar->dims[0] > 1 && matvar->dims[1] > 1) )
            fprintf(stderr,"Variable 'x' is not a vector!\n");
        Mat_VarFree(matvar);
    }

    Mat_Close(matfp);
    return EXIT_SUCCESS;
}

Iterating Over Variables in a MAT File
--------------------------------------

For some applications, the name of the variable may not be known ahead of time. For example, if the user needs to select a variable of interest, a list of variables should be obtained. Like reading a variable by name, there are two functions that will read the next variable in the MAT file: Mat_VarReadNext and Mat_VarReadNextInfo. The short example shown below opens a MAT file, and iterates over the variables in the file printing the variable name.
#include <stdlib.h>
#include <stdio.h>
#include "matio.h"

int
main(int argc,char **argv)
{
    mat_t    *matfp;
    matvar_t *matvar;

    matfp = Mat_Open(argv[1],MAT_ACC_RDONLY);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error opening MAT file \"%s\"!\n",argv[1]);
        return EXIT_FAILURE;
    }

    while ( (matvar = Mat_VarReadNextInfo(matfp)) != NULL ) {
        printf("%s\n",matvar->name);
        Mat_VarFree(matvar);
        matvar = NULL;
    }

    Mat_Close(matfp);
    return EXIT_SUCCESS;
}

Writing Variables
=================

A variable can be saved in a MAT file using the Mat_VarWrite function which has three arguments: the MAT file to write the variable to, a MATLAB variable structure, and a third option used to control compression options. The variable structure can be filled in manually, or created from helper routines such as Mat_VarCreate. Note that MATLAB, and thus matio, has no concept of a rank 1 array (i.e. vector). The minimum rank of an array is 2 (i.e. matrix). A vector is simply a matrix with one dimension length of 1.

Optionally, a variable can be appended to an existing variable of an HDF5 format MAT file by the Mat_VarWriteAppend function, which takes the same arguments as Mat_VarWrite as the first three arguments and the dimension as fourth argument. The dimension argument is index 1 based, i.e., if it is set to d, the variable is appended along the d-th dimension. If a variable is to be created for later appending, it always must be written by the Mat_VarWriteAppend function and Mat_VarWrite must not be called.

Writing Numeric Arrays
----------------------

Numeric arrays can be either real or complex. Complex arrays are encapsulated in the struct mat_complex_split_t data structure that contains a pointer to the real part of the data, and a pointer to the imaginary part of the data. The example program below writes two real variables x and y, and one complex variable z whose real and imaginary parts are the x and y variables respectively. Note the MAT_F_COMPLEX argument passed to Mat_VarCreate for z to indicate a complex variable.

#include <stdlib.h>
#include <stdio.h>
#include "matio.h"

int
main(int argc,char **argv)
{
    mat_t    *matfp;
    matvar_t *matvar;
    size_t    dims[2] = {10,1};
    double    x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10},
              y[10] = {11,12,13,14,15,16,17,18,19,20};
    struct mat_complex_split_t z = {x,y};

    matfp = Mat_CreateVer("test.mat",NULL,MAT_FT_DEFAULT);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error creating MAT file \"test.mat\"\n");
        return EXIT_FAILURE;
    }

    matvar = Mat_VarCreate("x",MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,x,0);
    if ( NULL == matvar ) {
        fprintf(stderr,"Error creating variable for 'x'\n");
    } else {
        Mat_VarWrite(matfp,matvar,MAT_COMPRESSION_NONE);
        Mat_VarFree(matvar);
    }

    matvar = Mat_VarCreate("y",MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,y,0);
    if ( NULL == matvar ) {
        fprintf(stderr,"Error creating variable for 'y'\n");
    } else {
        Mat_VarWrite(matfp,matvar,MAT_COMPRESSION_NONE);
        Mat_VarFree(matvar);
    }

    matvar = Mat_VarCreate("z",MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,&z,
                 MAT_F_COMPLEX);
    if ( NULL == matvar ) {
        fprintf(stderr,"Error creating variable for 'z'\n");
    } else {
        Mat_VarWrite(matfp,matvar,MAT_COMPRESSION_NONE);
        Mat_VarFree(matvar);
    }

    Mat_Close(matfp);
    return EXIT_SUCCESS;
}

Writing Cell Arrays
-------------------

Cell arrays are multidimensional arrays whose elements can be any class of variables (e.g. numeric, structure, cell arrays, etc.). To create a cell array, pass an array of matvar_t *. Detailed information on the MATLAB variable structure for cell-arrays is given in Cell Variables. The following example shows how to create a 3x1 cell array.

#include <stdlib.h>
#include <stdio.h>
#include "matio.h"

int
main(int argc,char **argv)
{
    mat_t    *matfp;
    matvar_t *cell_array, *cell_element;
    size_t    dims[2] = {10,1};
    double    x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10},
              y[10] = {11,12,13,14,15,16,17,18,19,20};
    struct mat_complex_split_t z = {x,y};

    matfp = Mat_CreateVer("test.mat",NULL,MAT_FT_DEFAULT);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error creating MAT file \"test.mat\"\n");
        return EXIT_FAILURE;
    }

    dims[0] = 3;
    dims[1] = 1;
    cell_array = Mat_VarCreate("a",MAT_C_CELL,MAT_T_CELL,2,dims,NULL,0);
    if ( NULL == cell_array ) {
        fprintf(stderr,"Error creating variable for 'a'\n");
        Mat_Close(matfp);
        return EXIT_FAILURE;
    }

    dims[0] = 10;
    dims[1] = 1;
    cell_element = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,x,0);
    if ( NULL == cell_element ) {
        fprintf(stderr,"Error creating cell element variable\n");
        Mat_VarFree(cell_array);
        Mat_Close(matfp);
        return EXIT_FAILURE;
    }
    Mat_VarSetCell(cell_array,0,cell_element);

    cell_element = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,y,0);
    if ( NULL == cell_element ) {
        fprintf(stderr,"Error creating cell element variable\n");
        Mat_VarFree(cell_array);
        Mat_Close(matfp);
        return EXIT_FAILURE;
    }
    Mat_VarSetCell(cell_array,1,cell_element);

    cell_element = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,&z,
                      MAT_F_COMPLEX);
    if ( NULL == cell_element ) {
        fprintf(stderr,"Error creating cell element variable\n");
        Mat_VarFree(cell_array);
        Mat_Close(matfp);
        return EXIT_FAILURE;
    }
    Mat_VarSetCell(cell_array,2,cell_element);

    Mat_VarWrite(matfp,cell_array,MAT_COMPRESSION_NONE);
    Mat_VarFree(cell_array);

    Mat_Close(matfp);

    return EXIT_SUCCESS;
}

Writing Structure Arrays
------------------------

Structure arrays are multidimensional arrays where each element of the array contains multiple data items as named fields. The fields of a structure can be accessed by name or index. A field can be a variable of any type (e.g. numeric, structure, cell arrays, etc.). The preferred method to create a structure array is using the Mat_VarCreateStruct2 function. After creating the structure array, the Mat_VarSetStructFieldByName and Mat_VarSetStructFieldByIndex functions can be used to set the fields of the structure array to a variable. The example below shows how to create a 2 x 1 structure array with the fields x, y, and z.

#include <stdlib.h>
#include <stdio.h>
#include "matio.h"

int
main(int argc,char **argv)
{
    mat_t    *matfp;
    matvar_t *matvar, *field;
    size_t    dims[2] = {10,1}, struct_dims[2] = {2,1};
    double    x1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10},
              x2[10] = {11,12,13,14,15,16,17,18,19,20},
              y1[10] = {21,22,23,24,25,26,27,28,29,30},
              y2[10] = {31,32,33,34,35,36,37,38,39,40};
    struct mat_complex_split_t z1 = {x1,y1}, z2 = {x2,y2};
    const char *fieldnames[4] = {"x","y","z",NULL};

    matfp = Mat_CreateVer("test.mat",NULL,MAT_FT_DEFAULT);
    if ( NULL == matfp ) {
        fprintf(stderr,"Error creating MAT file \"test.mat\"\n");
        return EXIT_FAILURE;
    }

    matvar = Mat_VarCreateStruct2("a", 2,struct_dims,fieldnames);
    if ( NULL == matvar ) {
        fprintf(stderr,"Error creating variable for 'a'\n");
        Mat_Close(matfp);
        return EXIT_FAILURE;
    }

    /* structure index 0 */
    field = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,x1,0);
    Mat_VarSetStructFieldByName(matvar,"x",0,field);
    field = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,y1,0);
    Mat_VarSetStructFieldByName(matvar,"y",0,field);
    field = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,&z1,
                MAT_F_COMPLEX);
    Mat_VarSetStructFieldByName(matvar,"z",0,field);

    /* structure index 1 */
    field = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,x2,0);
    Mat_VarSetStructFieldByName(matvar,"x",1,field);
    field = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,y2,0);
    Mat_VarSetStructFieldByName(matvar,"y",1,field);
    field = Mat_VarCreate(NULL,MAT_C_DOUBLE,MAT_T_DOUBLE,2,dims,&z2,
                MAT_F_COMPLEX);
    Mat_VarSetStructFieldByName(matvar,"z",1,field);

    Mat_VarWrite(matfp,matvar,MAT_COMPRESSION_NONE);
    Mat_VarFree(matvar);

    Mat_Close(matfp);
    return EXIT_SUCCESS;
}