Code covered by the BSD License  

4.1

4.1 | 10 ratings Rate this file 67 Downloads (last 30 days) File Size: 712 KB File ID: #16319

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

by

 

10 Sep 2007 (Updated )

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

| Watch this File

File Information
Description

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.

Acknowledgements

J Mat Io Matlab's Mat File I/O In Java inspired this file.

MATLAB release MATLAB 6.5 (R13)
Other requirements + .NET 2.0 (or later) Architecture to run assembly + Any application create with CSMatIO must include _both_ the csmatio.dll and the zlib.net.dll + Uses Visual Studio .NET 2005 for editing.
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (50)
27 Mar 2014 Roberto Conte Rosito  
21 Feb 2014 Tobias Otto-Adamczak

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

20 Jan 2014 Tobias Otto-Adamczak

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

09 Jan 2014 Diego

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!

22 Nov 2013 Tobias Otto-Adamczak

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.

21 Nov 2013 Diego

PS: I'm using csmatio rev07.

21 Nov 2013 Diego

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

07 Aug 2013 Tobias Otto-Adamczak

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

07 Aug 2013 chelli takfarinas

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

07 Aug 2013 Tobias Otto-Adamczak

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

06 Aug 2013 chelli takfarinas

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.

06 Aug 2013 Tobias Otto-Adamczak

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

05 Aug 2013 chelli takfarinas

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

20 Jun 2013 Tobias Otto-Adamczak

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

19 Jun 2013 Anton

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.

05 Jun 2013 Duc

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.

09 May 2013 Jen

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)

08 May 2013 Jayant

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.

03 May 2013 Jen

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!

30 Apr 2013 Tobias Otto-Adamczak

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

29 Apr 2013 Jen

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

29 Apr 2013 Jen

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.

29 Apr 2013 Tobias Otto-Adamczak

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

26 Apr 2013 Jen

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

15 Apr 2013 Tobias Otto-Adamczak

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

HTH, Tobias

13 Apr 2013 kushal

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.

23 Jan 2013 Tobias Otto-Adamczak

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

14 Jan 2013 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.

19 Dec 2012 M. Hakma  
30 Nov 2012 Tobias Otto-Adamczak

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

29 Nov 2012 Ettore

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?

25 Sep 2012 Tobias Otto-Adamczak

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

11 Jul 2012 Tobias Otto-Adamczak

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

HTH, Tobias

28 Feb 2012 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");

;)

07 Dec 2011 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).

01 Nov 2011 Tobias Otto-Adamczak

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

01 Nov 2011 Tobias Otto-Adamczak

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
...

28 Oct 2011 Qirong

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...

28 Oct 2011 farid

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!

28 Oct 2011 Tobias Otto-Adamczak

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

26 Oct 2011 Qirong

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?

30 Sep 2011 Tobias Otto-Adamczak

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.

08 Sep 2011 Markus W

Easy to use an very helpful

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

23 May 2011 J├Ârgen Ejr973jr

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.

20 May 2011 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.

08 Jan 2010 Lalit Parashar

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

28 Feb 2009 Mike

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.

07 Jul 2008 M D

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

24 Jun 2008 Pierluigi Fumi  
30 Oct 2007 Steffen S

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

Contact us