module NMatrix::IO::Matlab

Reader (and eventually writer) of Matlab .mat files.

The .mat file format is documented in the following link:

Public Class Methods

complex_merge(p1, p2, p3) click to toggle source

Take two byte-strings (real and imaginary) and treat them as if they contain a sequence of data of type dtype. Merge them together and return a new string.

static VALUE nm_rbstring_merge(VALUE self, VALUE rb_real, VALUE rb_imaginary, VALUE rb_dtype) {

  // Sanity check.
  if (RSTRING_LEN(rb_real) != RSTRING_LEN(rb_imaginary)) {
    rb_raise(rb_eArgError, "real and imaginary components do not have same length");

  nm::dtype_t dtype = nm_dtype_from_rbsymbol(rb_dtype);
  size_t len        = DTYPE_SIZES[dtype];

  char *real        = RSTRING_PTR(rb_real),
       *imag        = RSTRING_PTR(rb_imaginary);

  char* merge       = NM_ALLOCA_N(char, RSTRING_LEN(rb_real)*2);

  size_t merge_pos  = 0;

  // Merge the two sequences
  for (size_t i = 0; i < (size_t)RSTRING_LEN(rb_real); i += len) {

    // Copy real number
    memcpy(merge + merge_pos, real + i, len);
    merge_pos += len;

    // Copy imaginary number
    memcpy(merge + merge_pos, imag + i, len);
    merge_pos += len;

  return rb_str_new(merge, merge_pos);
Alias for: load_mat
load(mat_file_path) → NMatrix click to toggle source
load_mat(mat_file_path) → NMatrix

Load a .mat file and return a NMatrix corresponding to it.

# File lib/nmatrix/nmatrix.rb, line 72
def load_mat(file_path), "rb+")).to_ruby
Also aliased as: load
repack(p1, p2, p3) click to toggle source

Take a string of bytes which represent MATLAB data type values and repack them into a string of bytes representing values of an NMatrix dtype (or itype).

Returns what appears to be a Ruby String.


  • str

    the data

  • from

    symbol representing MATLAB data type (e.g., :miINT8)

  • type

    either :itype or some dtype symbol (:byte, :uint32, etc)

static VALUE nm_rbstring_matlab_repack(VALUE self, VALUE str, VALUE from, VALUE type) {
  nm::io::matlab_dtype_t from_type = matlab_dtype_from_rbsymbol(from);
  uint8_t to_type;

  if (SYMBOL_P(type)) {
    if (rb_to_id(type) == rb_intern("itype")) {
      if (sizeof(size_t) == sizeof(int64_t)) {
        to_type = static_cast<int8_t>(nm::INT64);
      } else if (sizeof(size_t) == sizeof(int32_t)) {
        to_type = static_cast<int8_t>(nm::INT32);
      } else if (sizeof(size_t) == sizeof(int16_t)) {
        to_type = static_cast<int8_t>(nm::INT16);
      } else {
        rb_raise(rb_eStandardError, "unhandled size_t definition");
    } else {
      to_type = static_cast<uint8_t>(nm_dtype_from_rbsymbol(type));
  } else {
    rb_raise(rb_eArgError, "expected symbol for third argument");

  // For next few lines, see explanation above NM_MATLAB_DTYPE_TEMPLATE_TABLE definition in io.h.
  if (to_type >= static_cast<uint8_t>(nm::COMPLEX64)) {
    rb_raise(rb_eArgError, "can only repack into a simple dtype, no complex/VALUE");

  // Do the actual repacking -- really simple!
  NM_MATLAB_DTYPE_TEMPLATE_TABLE(ttable, nm::io::matlab_cstring_to_dtype_string, char*, size_t& result_len, const char* str, size_t bytes);

  size_t repacked_data_length;
  char* repacked_data = ttable[to_type][from_type](repacked_data_length, RSTRING_PTR(str), RSTRING_LEN(str));

  // Encode as 8-bit ASCII with a length -- don't want to hiccup on \0
  VALUE result = rb_str_new(repacked_data, repacked_data_length);
  NM_FREE(repacked_data); // Don't forget to free what we allocated!

  return result;