File Exchange

image thumbnail

CSMatIO: MAT-file I/O API for .NET 2.0

version 1.0 (712 KB) by

Package contains Matlab's MAT-File I/O API for .NET 2.0. Supports Matlab 5 MAT-file format.

36 Downloads

Updated

View License

CSMatIO a .NET Library is a Matlab MAT-File I/O API for Microsoft's .NET 2.0 Architecture written entirely in C#. CSMatIO has the ability to read, write, and manipulate binary Level 5 MAT-Files.

Currently supported data types:
+ Double array
+ Single array
+ Char array
+ Structure
+ Cell array
+ Sparse array
+ Int8 array
+ UInt8 array
+ Int16 array
+ UInt16 array
+ Int32 array
+ UInt32 array
+ Int64 array
+ UInt64 array

Note:
The zlib.net.dll file is used to compress and decompress MAT-file data.

Comments and Ratings (57)

Adhara

Adhara (view profile)

I the library works well, but I have a couple of questions about the supported formats. Is still v5 the only one supported? Thanks.

Greg Brissey

Hi,
can't seem to be able to post on Sourceforge, so I'll post here.
I'm trying to duplicate a struct with csmatio
The struct is 1x21 where each column has a field name then followed by values (approx 20 rows). thus there are 21 fields or variable names with 20 values (rows).
I can create the 1x21 struct, but I can seem to add the columns (using MLDouble) appropriately, I've tried a few combinations but always Matlab throws an error that it can not read the file.

Matlab output of struct I'm trying to create:

1x21 struct array with fields:

cfreq_Hz
fspan_Hz
Res_BW_Hz
Vid_BW_Hz
SweepTime_s
AbsStart_dBm
AbsStop_dBm
PeakExcursion_dB
PeakThreshold_dBm
Atten_dB
Detector1
Detector2
npts
rangeIndex
ActResBandwidth_Hz

spec_data.ranges.cfreq_Hz
list 21 values,

Documentation is not very clear on this.
How would I do this.
Thanks

Ok, seems like I'm able to post my question in sourceforge.

I'll add the same topic there.

@+
rv.

Hi all,

As I cannot post on the new https://sf.net/projects/csmatio/ discussion page, I'll post my question here.

Let's say I have some *.mat files in a zip file and that I need to unzip this file in memory because of some limitations (no access to the disk system for io operations).

I was thinking that using the class MatFileInputStream will be ok, but then I realize that there is no (easy) way to retrieve the arrays like in the MatFileReader class (Content method).

So is there a way to achieve this with the current implementation of csmatio... without updating the code?

Thanks in advance,

@+
rv.

This download and discussion page is outdated. Please visit https://sf.net/projects/csmatio/ instead.

Ben Human

Hi,
How do I create a Matlab cell array from a C# List<String> ? Any help would be much appreciated!
Ben

Hey, how can I write DateTime arrays? Cell arrays work just fine but they vastly increase the output file size...

Hi folks,
I created a public discussion forum for the csmatio code on SourceForge today:
https://sourceforge.net/p/csmatio/discussion/general/
I'd like to discuss further topics on csmatio at SourceForge.

Greetings
Tobias

Hi Diego, this is a bug. Please create a ticket on sourceforge for that:
http://sf.net/p/csmatio/tickets/

Diego

Diego (view profile)

Hi Tobias,
I need to create empty double variables in the mat file.

I've tried as follows:

MatFileWriter mfw;
matDataStream = new List<MLArray>();
matDataStream.Add(new MLEmptyArray("a"));
mfw = new MatFileWriter("test.mat",matDataStream,true);

This code generates a System.InvalidCastException when trying to write the file, because it is impossible to cast an object of type 'csmatio.types.MLEmptyArray' to 'csmatio.types.MLNumericArray`1[System.Double]'.

Any suggestions?

Thanks again for your support!

Hi Diego, this is a bug. I created a ticket on sourceforge for that: https://sourceforge.net/p/csmatio/tickets/1/ Please switch over to sourceforge to discuss that.

Diego

Diego (view profile)

PS: I'm using csmatio rev07.

Diego

Diego (view profile)

Hi, thank you for the library. It's really useful. I've found a bug when writing a mat file containing variables of type single. The file is generated, but opening the file Matlab returns the following error:

??? Error using ==> load
Can't read file C:\csharp_matlab.mat.

Here the code I wrote to generate the file:

MatFileWriter mfw;
List<MLArray> MLdata = new List<MLArray>();
double [] val = {1,2};
float[][] val_float = new float[2][];
val_float[0] = new float[] { 1 };
val_float[1] = new float[] { 2 };

MLdata.Add(new MLDouble("pippo",val,1));
MLdata.Add(new MLSingle("pippo_single", val_float));

mfw = new MatFileWriter(@"C:\csharp_matlab.mat",MLdata,true);

Could you help me, please?
Thanks in advance
Diego

Hi chelli, here is the complete example:

// create a reader for the file
MatFileReader mfr = new MatFileReader("chelli1.mat");

// get a reference to the matlab struct array named 'spin1'
MLStructure mlStruct = mfr.Content["spin1"] as MLStructure;

for (int i = 0; i < mlStruct.Size; ++i)
{
// get reference to struct member 'spinIm' (5x5 double array)
MLDouble mlSpin = mlStruct["spinIm", i] as MLDouble;

// get values
double[][] spin = mlSpin.GetArray();
}

HTH
Tobias

thank you very much
the solution is to use
MLDouble mlDouble = mlStruct.AllFields[index] as MLDouble;
double x = MLDouble.Get (index);

Hi chelli,

a) For reading struct arrays you can use
mlStruct["Version", index] instead of mlStruct["Version"].

b) For reading a 5x5 double matrix instead a scalar double value you can use
mlW.GetArray() instead of mlW.Get(0).

HTH
Tobias

hi;
thank you for your help;
but in my files I have a variable of type 1xN struct array with fields:
spinIm(5x5);
how I Get data without using ContentToString
thanks.

Hi chelli,

reading of structs has a bug in the original 2007 version of David. Make sure you use the latest csmatio version from http://sf.net/projects/csmatio/

The csmatio source code contains a demo file named "struct.mat". Here is some demo code to read the content of this mat file:

// create a reader for the file
MatFileReader mfr = new MatFileReader("struct.mat");

// get a reference to the matlab struct named 'X'
MLStructure mlStruct = mfr.Content["X"] as MLStructure;

// get references to some struct member objects
MLChar mlVersion = mlStruct["Version"] as MLChar;
MLDouble mlW = mlStruct["w"] as MLDouble;

// get values from struct members
string version = mlVersion.GetString(0); // "1.0.5.23354"
double w = mlW.Get(0); // 3874.0

HTH
Tobias

hi;
I have files that contain structures;
how to read them in C#;
thank you;

Thanks Anton! I fixed this. Latest version is available on sourceforge:
http://sf.net/projects/csmatio/

Anton

Anton (view profile)

File MLNumericArray.cs, line 76.
The Flags property should be
get{return (int)((uint)(base._type & MLArray.mtFLAG_TYPE) |(uint(base._attributes & 0xFFFFFF00));}

or it will make all the numberic data written as Double.

Duc

Duc (view profile)

Hi, I found a bug in the library.
File MLArray.cs, line 103.
The Flags property should be
get{ return (int)((uint)(_type & mtFLAG_TYPE) | (uint)(_attributes & 0xFFFFFF00)); }

or it will make all the numberic data written as Double.

And thank you very much for creating this awesome library.
Regards.

Jen

Jen (view profile)

Jayant,once you created the 3D array, then use: array.Set(value,row_ind,col_index). For example, your 3D array is m*n*3,for 1st dimension, use array.Set(value,row_ind,col_index);for 2nd dimension, use array.Set(value,row_ind,col_index+n);for 3rd dimension, use array.Set(value,row_ind,col_index+2n)

Jayant

Jayant (view profile)

How can we save a 3 dimensional array of type MLUInt8? I am able to create the array of 3 dimensions but I am not able to figure out how to populate the data inside it.

Jen

Jen (view profile)

I took a look at inside of it and found the data types are little confusing. I will see what I can do, thanks for the trust. Let's solve this problem, everyone!

Hi Jen, thank you for sharing this. AFAIK David is currently not working on the code. Neither do I. But if you could make some improvements I would be glad to test your patches and update the code on sourceforge.

HTH, Tobias

Jen

Jen (view profile)

one more thing, CSMatIO has no problem reading uint16/int8 files that is created by CSMatIO itself.
It only has problem when I tried Matlab "save()" function created mat files.
Thank you

Jen

Jen (view profile)

It still doesn't work Tobias. I didn't make it very accurate in the last post: For uint16, error can be catched, saying "invalid binary MAT-file!"; For int8, the debugger stopped at ln386 in MatFileReader.cs and error message says "Additional information: Unable to cast object of type 'csmatio.types.MLInt8' to type'csmatio.types.MLNumericArray`1[System.Byte]'."
Has anyone tried on uint16 or int8 before?
Thank you for your reply.

Hi Jen, this might be due to one of the few shortcomings of Davids original code. Have a look at the latest version at sourceforge and tell me if it behaves the same way: https://sourceforge.net/projects/csmatio/files/

HTH, Tobias

Jen

Jen (view profile)

I have no problem reading in Uint8 and Double.
But I couldn't read in "int8" and "uint16" type MAT file, debug stopped at Ln386 in "MatFileReader.cs", and error message says"Additional information: Unable to cast object of type 'csmatio.types.MLInt8' to type'csmatio.types.MLNumericArray`1[System.Byte]'."
What might be wrong? Thank you

Hello kushal, CSMatIO is about .NET, not Java. For Java consider JMatIO instead.

HTH, Tobias

kushal

kushal (view profile)

suppose a mat file consist of multiple matrices and tensor,

how to read those matrices as it is in local java variable so as to perform the operations on those variables such as transpose etc.

e.g: say sample.mat contains
A(mxn),
B(m x n x k),
C(m x k),
D(n x k)

how to read these matrices in java and store them with their original dimensions as it is.

Hi Laurent, you can easily create a 3D double array as follows:

// init 3D double array (2x3x4 elements)
int[] dims = new int[] { 2, 3, 4 };
MLDouble array3Dim = new MLDouble("cube", dims);

HTH, Tobias

Laurent

Very nice and useful library.

A question for Tobias, which was asked (I quote) "How to read the content of a three-dimensional double array with this library."

My question is : how to create a 3D double array with this library ? Methods of MLDouble don't seem to enable that kind of thing...

Nice work anyway.

M. Hakma

Le me give you a basic example how to create nested matlab vars with this lib.

// suppose we have following C# struct

public struct Score
{
public string Name;
public double Value;
}

// initialize an struct object of that type

Score highscore;
highscore.Name = "David";
highscore.Value = 47.3;

// create a corresponding MATLAB structure

MLStructure structure = new MLStructure("highscore", new int[] { 1, 1 });

// create a MATLAB char and double variable and add it to the structure

MLChar scoreName = new MLChar("", highscore.Name);
MLDouble scoreValue = new MLDouble("", new double[] { highscore.Value }, 1);
structure["Name", 0] = scoreName;
structure["Value", 0] = scoreValue;

// save the structure as mat file using MatFileWriter

List<MLArray> mlList = new List<MLArray>();
mlList.Add(structure);
MatFileWriter mfw = new MatFileWriter("data.mat", mlList, false);

HTH, Tobias

Ettore

Ettore (view profile)

I need to write some nested vars in .mat file, like:
a.b.var1=10
a.b.var2=20

To my understanding, within the MatlabFileWriter, i can't do:
data.Add("a.b.var1", 10)

but I need to implement something like
- check if 'a' exists, create it if not
- check if 'b' exists under 'a', create it if not
- check if 'var' exists under 'b', create it if not
- set value and save

Is that correct?

Today I was asked how to read the content of a three-dimensional double array with this library. The same goes for arrays with four or more dimensions.

So lets assume we have a 220x180x33 double array called "cube" and we want to read what is in matlab syntax "cube(7,18,29)":

// get a reference to our matlab 'cube' double matrix
MLDouble mlCube = (mfr.Content["cube"] as MLDouble);
if (mlCube != null)
{
// calculate the index of our element
idx = 7-1 + (18-1)*220 + (29-1)*180*220;
// now get the double value
double value = mlCube.Get(idx);
}

HTH, Tobias

Hi all, I fixed some issues in this really useful libray. Have a look at https://sourceforge.net/projects/csmatio/files/

HTH, Tobias

diiiego83

ok good work David.
Ther's an error if you try to open a mat file with data of "single" class.
You forget the single case in MatFileReader.cs method ReadMatrix (Add this)

case MLArray.mxSINGLE_CLASS:
mlArray = new MLSingle(name, dims, type, attributes);
//read real
tag = new ISMatTag(buf);
tag.ReadToByteBuffer(((MLNumericArray<double>)mlArray).RealByteBuffer,
(ByteStorageSupport)mlArray);

// read complex
if (mlArray.IsComplex)
{
tag = new ISMatTag(buf);
tag.ReadToByteBuffer(((MLNumericArray<double>)mlArray).ImaginaryByteBuffer,
(ByteStorageSupport)mlArray);
}
break;

The keys in the internal structure has been saved with "\0". For Example in MlStructure.cs method ContentToString change :
sb.Append("\t" + key + " : " + this[key].ContentToString() + "\n");
with :
sb.Append("\t" + key.Replace("\0","") + " : " + this[key].ContentToString() + "\n");

;)

Markus W

Had problems reading mat-files with 2-dim arrays with larger number of elements. Saving the file with -v6 option solved the problem (so far).

Hi Qirong, I give you a very simple but more complete example. I tested this with Matlab R2006b and Visual Studio 2005.

Consider you created a "mydata.mat" file containing a 1x10 double matrix using matlab like this:

>> squares = [1:10].^2
>> save('mydata.mat', 'squares')

You can then use the following C# code to get this data into a .NET double-Array:

namespace csmatio_test
{
using System;
using csmatio.io;
using csmatio.types;

class Program
{
// this array receives the matlab data
static double[] squares;

static void Main(string[] args)
{
// create a reader for the file
MatFileReader mfr = new MatFileReader("mydata.mat");

// get a reference to out matlab 'squares' double matrix
MLDouble mlSquares = (mfr.Content["squares"] as MLDouble);
if (mlSquares != null)
{
// now get the double values
double[][] tmp = mlSquares.GetArray();
squares = tmp[0];
}
}
}
}

HTH, Tobias

Hi farid, csmatio uses zlib to compress/decompress matlab file data. There are several possibilities why zlib throws this exception; for example you might think of
(a) file format not supported (csmatio does not support all kinds of mat files)
(b) corrupt file content
(c) bug in csmatio
...

Qirong

Qirong (view profile)

So I know that the data is double array, how can I cast the MLArray type into MLDouble type? I tried

MatFileReader mfr = new MatFileReader(currentName);
foreach (MLArray mla in mfr.Data)
{
MLDouble da = mla;
}

But apparently this doesn't work...

farid

farid (view profile)

hi all.
I'm trying to read a mat file but i receive this error

==========================
Error in reading MAT-file 'initialize\matfile-1.mat':
csmatio.io.MatlabIOException: Could not decompress data: zlib.ZStreamException: inflating:
at zlib.ZOutputStream.Write(Byte[] b1, Int32 off, Int32 len)
at csmatio.io.MatFileReader.Inflate(Stream buf, Int32 numOfBytes)
at csmatio.io.MatFileReader.Inflate(Stream buf, Int32 numOfBytes)
at csmatio.io.MatFileReader.ReadData(Stream buf)
at csmatio.io.MatFileReader..ctor(String fileName, MatFileFilter filter)
==========================

what is the cause of this error message?
pleas help .... the situation is urgent!

First, you might want to get a reference to your matlab variable:

var mfr = new MatFileReader(fileName);
MLArray mlArrayRetrieved = mfr.GetMLArray("my_array");

Second, you need to find out of which type mlArrayRetrieved really is (as MLArray is only a base class) and you cast into the real type. Depending on the real type there are different Methods/Properties that represent the data.

HTH, Tobias

Qirong

Qirong (view profile)

How do I load data using this library? I followed the test application and it only uses the function MatFileReader.ContentToString() to access the content. Is that the only way I can access the data? And then parse the string to get the real data?

Really useful library. However it has some bugs (struct field access is buggy, writing empty strings doesn't work) und is somehow incomplete (unsupported data types). I try to provide some fixes in the next days.

Markus W

Easy to use an very helpful

Writing empty string seems to result in exception. Any workaround?

Support for enumerations?

Any plans to add support for enumerations using declared as:
classdef(Enumeration) AdapRequestEnum < int32 ...

I have not found any description of the internal representation in MAT file format.

Bart Ribbens

Does there exist a binary Level 7 Mat fileformat?

In the latest document (MAT-File Format
Version 7) they still use the Level 5 binary.

Any plans to upgrade it to manipulate binary Level 7 MAT-Files.

Mike

Mike (view profile)

Writes to binary memory stream which runs out of memory at ~270 MB (.NET managed heap limitation, I believe) before being written to disk. Would be nice to have the option to take a performance hit but stream directly to disk, enabling creation of larger files.

M D

Missing cases MLArray.mxUINT16_CLASS, MLArray.mxINT16_CLASS, MLArray.mxUINT32_CLASS & MLArray.mxINT32_CLASS in the method ReadMatrix of MatFileReader class

Pierluigi Fumi

Steffen S

A bit tricky to get into. But once you got it its easy to use. Works stable.

MATLAB Release
MATLAB 6.5 (R13)
Acknowledgements

Inspired by: JMatIO - Matlab's MAT-file I/O in JAVA

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video