ami-iit / matio-cpp

A C++ wrapper of the matio library, with memory ownership handling, to read and write .mat files.
https://ami-iit.github.io/matio-cpp/
BSD 2-Clause "Simplified" License
59 stars 9 forks source link
cmake cpp cpp14 cxx cxx14 eigen hdf5 mat mat-files matio matio-cpp matlab matlab-mat matlab-matrix ndimensional-arrays octave

matio-cpp C++ Standard

matio-cpp is a C++ wrapper for the matio library, automatically dealing with memory allocation and deallocation. It can be used for reading and writing binary MATLAB .mat files from C++, without the need to access or rely on MATLAB's own shared libraries.

Overview

Installation

Dependencies

The depencies are CMake (minimum version 3.10) and matio. While we suggest to follow the build instructions provided in the matio home page, it can also installed from common package managers:

Eigen is an optional dependency. If available, some conversions are defined.

For running the tests, it is necessary to install Catch2. Where supported, valgrind can be installed to check for memory leaks.

Linux/macOS

git clone https://github.com/ami-iit/matio-cpp
cd matio-cpp
mkdir build && cd build
cmake ../
make
[sudo] make install

Notice: sudo is not necessary if you specify the CMAKE_INSTALL_PREFIX. In this case it is necessary to add in the .bashrc or .bash_profile the following lines:

export matioCpp_DIR=/path/where/you/installed/

Windows

With IDE build tool facilities, such as Visual Studio:

git clone https://github.com/ami-iit/matio-cpp
cd matio-cpp
mkdir build && cd build
cmake ..
cmake --build . --target ALL_BUILD --config Release
cmake --build . --target INSTALL --config Release

In order to allow CMake finding matio-cpp, it is necessary that the installation folder is in the PATH.

Inclusion

matio-cpp provides native CMake support which allows the library to be easily used in CMake projects

In order to use matio-cpp in your project, add the following in your CMakeLists.txt

find_package(matioCpp REQUIRED)

# ...

target_link_libraries(yourTarget PRIVATE matioCpp::matioCpp)

Supported Data Types

matio-cpp can handle the following data types:

All these types can be read/written from/to .mat files.

Example of usage

Read a .mat file

#include <matioCpp/matioCpp.h>

// ...

matioCpp::File input("input.mat");
// You can check if input is open with the isOpen() method
matioCpp::CellArray cellArray = input.read("cell_array").asCellArray(); //Read a Cell Array named "cell_array"
matioCpp::Element<double> doubleVar = cellArray({1,2,3}).asElement<double>(); //Get the element in the cell array at position (1,2,3) (0-based), casting it as a double Element
doubleVar = 3.14; //Set the doubleVar to a new value
assert(cellArray({1,2,3}).asElement<double>()() == 3.14); //Also the original cell array is modified, but not in the file.

Write a .mat file

#include <matioCpp/matioCpp.h>

// ...

matioCpp::File file = matioCpp::File::Create("test.mat"); //If the file already exists, use the same cnstructor as the example above

std::vector<double> in = {2.0,4.0,6.0,8.0};
matioCpp::Vector<double> out("test_vector");
out = in;
file.write(out);

matioCpp::String testString("string_name");
testString = "string content";
file.write(testString);

It is possibile to convert common types to matioCpp types with the function matioCpp::make_variable. Examples:

std::vector<double> stdVec = {1.0, 2.0, 3.0, 4.0, 5.0};
auto toMatioVec = matioCpp::make_variable("test", stdVec);

std::array<float,3> array = {1.0, 2.0, 3.0};
auto toMatioArray = matioCpp::make_variable("test", array);

int classicalArray[] = {1, 2, 3};
auto toMatioClassic = matioCpp::make_variable("test", matioCpp::make_span(classicalArray, 3));

std::string string("something");
auto toMatioString = matioCpp::make_variable("name", string);

std::vector<bool> vecOfBool = {true, false, true};
auto toVecofBool = matioCpp::make_variable("vecOfBool", vecOfBool);

auto matioDouble = matioCpp::make_variable("double", 5.0);

auto matioBool = matioCpp::make_variable("bool", true);

auto matioInt = matioCpp::make_variable("int", 2);

auto matioChar = matioCpp::make_variable("char", 'f');

std::vector<std::string> stringVector = {"Huey", "Dewey", "Louie"};
auto matioCell = matioCpp::make_variable("stringVector", stringVector);

If eigen is available, it is also possible to convert from and to eigen types:

matioCpp::Vector<double> vector("vector", 5);                                               
Eigen::VectorXd eigenVec = matioCpp::to_eigen(vector);                                      
matioCpp::MultiDimensionalArray<float> matioCppMatrix("matrix"); 

Eigen::MatrixXf toEigenMatrix = matioCpp::to_eigen(matioCppMatrix);

Eigen::Matrix3f eigenMatrix;                                                    
eigenMatrix << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0;                     
auto toMatioMatrix = matioCpp::make_variable("testMatrix", eigenMatrix);        
Eigen::Vector3i eigenVec;      
eigenVec << 2, 4, 6;                                                            
auto toMatioEigenVec = matioCpp::make_variable("testEigen", eigenVec);          

matioCpp also exploits visit_struct to parse C++ structs into matioCpp structs. Example:

struct testStruct
{
    int i{1};
    double d{2.0};
    std::string s{"test"};
    std::vector<double> stdVec = {1.0, 2.0, 3.0, 4.0, 5.0};
    int* notSupported = nullptr;
    std::vector<std::string> stringVector = {"Huey", "Dewey", "Louie"};
    std::vector<bool> vecOfBool = {true, false, true};
};
VISITABLE_STRUCT(testStruct, i, d, s, stdVec, vecOfBool, stringVector);

//----------

testStruct s;
matioCpp::Struct automaticStruct = matioCpp::make_variable("testStruct", s);

Example

You can check the example in the example folder on how to include and use matioCpp.

Known Limitations

Similar Projects

Maintainers