開源Math.NET基礎數學類庫使用(03)C#解析Matlab的mat格式

原文: 【原創】開源Math.NET基礎數學類庫使用(03)C#解析Matlab的mat格式

 開源Math.NET基礎數學類庫使用系列文章總目錄: html

  1.開源.NET基礎數學計算組件Math.NET(一)綜合介紹 正則表達式

  2.開源.NET基礎數學計算組件Math.NET(二)矩陣向量計算
編程

  3.開源.NET基礎數學計算組件Math.NET(三)C#解析Matlab的mat格式數組

  4.開源.NET基礎數學類庫使用Math.NET(四)C#解析Matrix Marke數據格式安全

  5.開源.NET基礎數學類庫使用Math.NET(五)C#解析Delimited Formats數據格式機器學習

  6.開源.NET基礎數學類庫使用Math.NET(六)數值分析之線性方程直接求解ide

  7.開源.NET基礎數學類庫使用Math.NET(七)經常使用的一些數學常數 函數

  8.開源.NET基礎數學類庫使用Math.NET(八)C#進行數值積分post

  9.開源.NET基礎數學類庫使用Math.NET(九)相關數論函數使用學習

10.開源.NET基礎數學類庫使用Math.NET(十)C#進行數據統計

11.開源.NET基礎數學類庫使用Math.NET(十一)C#計算相關係數

12.開源.NET基礎數學類庫使用Math.NET(十二)隨機數擴展方法

13.開源.NET基礎數學類庫使用Math.NET(十三)C#實現其餘隨機數生成器

14.開源.NET基礎數學類庫使用Math.NET(十四)安全的隨機數生成器擴展

後續繼續更新中。。如文章連接打開有誤,請關注博客,由於文章正在編輯修改中,全部已經列出的目錄都將在1個月以內發表。

前言

  本人在09年使用該組件的時候,主要緣由也是爲了替代Matlab,進行相關數學計算,如今依然有不少人關注Matlab計算,特別是學生,而不少也在使用C#,因此這些人一般因爲我的能力有限(沒法精通某一個門語言來解決綜合問題),沒法單純的經過C#或者Matlab來解決問題,就想經過混合編程來調用完成,其實本人也作過大量的Matlab.NET混合編程研究,並且也我的製做了一套視頻教程,編寫過不少文章,能夠參考以下文章:

1.國內第一部Matlab和C#.Net混合編程入門級視頻教程【徹底免費】

2.Matlab.NET混合編程調用Figure窗體

3.Matlab.NET混合編程技巧之——直接調用Matlab內置函數(附源碼) 

4.Matlab.NET混合編程技巧之——找出Matlab內置函數 

5.Matlab與.NET基於類型安全的接口混合編程入門

6.Matlab與.NET混合編程解決人臉識別問題 

  鑑於此,我也提醒過不少人,在.NET中可使用Math.NET組件來替代Matlab的相關工做,可能效果不太好。今天就來介紹一個比較適用的功能,利用Math.NET提供的功能,使用C#來讀寫Matlab的mat數據格式,這個功能的使用場景也很普遍,固然多是研究偏多,你們思想能夠放得更遠。

  若是本文資源或者顯示有問題,請參考 本文原文地址http://www.cnblogs.com/asxinyu/p/4265972.html

1.Mat數據格式

  用過一段matlab的人都知道,在matlab的工做空間中,能夠將變量保存爲mat數據格式,下次在程序中直接讀取和進行計算,很是方便。之前也沒有具體研究過這個格式,也趁這個寫博客的機會,一塊兒來看看這個東西的做用和組成。雖然使用Math.NET提供的程序讀取和寫入Mat文件都很簡單,但簡單之餘,瞭解一點其餘知識也是不錯的。

  Mat文件格式,實際上使用的是一種通用的數值數據存儲格式Hierarchical Data Format(HDF),該格式最早是由美國國家超級計算應用中心開發的,後來由HDF非盈利組織資助,進行不但完善和推廣。這個格式的使用是很是普遍的(使用BSD許可證),例如一些大名鼎鼎的商業和非商業軟件LabVIEW,MATLAB,Scilab,Octave,Mathematica等都支持該格式,該格式目前主要有HDF4和HDF5。 Mat文件格式最新的7.3版是基於HDF5的。

有關HDF文件格式和Mat格式的資料以下:

wikipedia:http://en.wikipedia.org/wiki/Hierarchical_Data_Format

Matlab官方:http://cn.mathworks.com/help/matlab/import_export/mat-file-versions.html

HDF官方:http://www.hdfgroup.org/ 

  Mat文件格式分爲2個等級(目前我知道的) Level 4和 Level 5。Level 4 Mat文件格式支持只支持2維矩陣和字符串;而Level 5支持更多,如多維數組,字符串數組,Cell數組,稀疏矩陣,對象,結構等都支持。本文介紹的MathNet.Numerics.Data.Matlab是直接支持Level-5類型的,全部更強大。

2.Mat格式在Matlab中的使用

   Matlab中mat數據的保存和讀取很是簡單,只須要使用Save和load命令便可。對Matlab熟悉的朋友能夠隨便打開matlab敲幾個命令就能夠了,因爲電腦太慢,前段時間把Matlab卸載了,這裏就只介紹mat格式讀取和保存的語法,實際的使用也是比較簡單的。

http://www.ilovematlab.cn/thread-78257-1-1.html

●save:將工做區中的全部變量保存在當前工做區中的文件中,文件名爲 matlab.mat,MAT文件能夠經過load函數再次導入工做區,MAT函數能夠被不一樣的機器導入,甚至能夠經過其餘的程序調用。
●save('filename'):將工做區中的全部變量保存爲文件,文件名由filename指定。若是filename中包含路徑,則將文件保存在相應目錄下,不然默認路徑爲當前路徑。
●save('filename', 'var1', 'var2', ...):保存指定的變量在 filename 指定的文件中。
●save('filename', '-struct', 's'):保存結構體s中所有域做爲單獨的變量。
●save('filename', '-struct', 's', 'f1', 'f2', ...):保存結構體s中的指定變量。
● save('-regexp', expr1, expr2, ...):經過正則表達式指定待保存的變量需知足的條件。
● save('..., 'format'),指定保存文件的格式,格式能夠爲MAT文件、ASCII文件等。

MATLAB中導入數據一般由函數load實現,該函數的用法以下:
●load:若是matlab.mat文件存在,導入matlab.mat中的全部變量,若是不存在,則返回error。
●load filename:將filename中的所有變量導入到工做區中。
●load filename X Y Z ...:將filename中的變量X、Y、Z等導入到工做區中,若是是MAT文件,在指定變量時可使用通配符「*」。
●load filename -regexp expr1 expr2 ...:經過正則表達式指定須要導入的變量。
●load -ascii filename:不管輸入文件名是否包含有擴展名,將其以ASCII格式導入;若是指定的文件不是數字文本,則返回error。
●load -mat filename:不管輸入文件名是否包含有擴展名,將其以mat格式導入;若是指定的文件不是MAT文件,則返回error。

3.C#讀取Mat數據格式

  Math.NET中有關Mat數據格式讀寫的組件是MathNet.Numerics.Data.Matlab,Mat數據格式的讀取主要用MatlabReader類,解析的功能函數就是下面這段代碼:

 1 /// <summary>Extracts all matrix blocks in a format we support from a stream.</summary>
 2 internal static List<MatlabMatrix> ParseFile(Stream stream)
 3 {
 4     var matrices = new List<MatlabMatrix>();
 5 
 6     using (var reader = new BinaryReader(stream))
 7     {
 8         // skip header (116 bytes)
 9         // skip subsystem data offset (8 bytes)
10         // skip version (2 bytes)
11         reader.BaseStream.Position = 126;
12 
13         // endian indicator (2 bytes)
14         if (reader.ReadByte() != LittleEndianIndicator)
15         {
16             throw new NotSupportedException(Resources.BigEndianNotSupported);
17         }
18 
19         // set position to first data element, right after full file header (128 bytes)
20         reader.BaseStream.Position = 128;
21         var length = stream.Length;
22 
23         // for each data element add a MATLAB object to the file.
24         while (reader.BaseStream.Position < length)
25         {
26             // small format: size (2 bytes), type (2 bytes), data (4 bytes)
27             // long format: type (4 bytes), size (4 bytes), data (size, aligned to 8 bytes)
28 
29             DataType type;
30             int size;
31             bool smallBlock;
32             ReadElementTag(reader, out type, out size, out smallBlock);
33 
34             // read element data of the size provided in the element header
35             // uncompress if compressed
36             byte[] data;
37             if (type == DataType.Compressed)
38             {
39                 data = UnpackCompressedBlock(reader.ReadBytes(size), out type);
40             }
41             else
42             {
43                 data = new byte[size];
44                 reader.Read(data, 0, size);
45                 SkipElementPadding(reader, size, smallBlock);
46             }
47 
48             if (type == DataType.Matrix)
49             {
50                 using (var matrixStream = new MemoryStream(data))
51                 using (var matrixReader = new BinaryReader(matrixStream))
52                 {
53                     matrixReader.BaseStream.Seek(20, SeekOrigin.Current);
54                     var matrixDim = matrixReader.ReadInt32()/8;
55                     if (matrixDim > 2)
56                     {
57                         continue;
58                     }
59 
60                     matrixReader.BaseStream.Seek(10, SeekOrigin.Current);
61                     int matrixSize = matrixReader.ReadInt16();
62                     if (matrixSize == 0)
63                     {
64                         matrixSize = matrixReader.ReadInt32();
65                     }
66 
67                     var matrixName = Encoding.ASCII.GetString(matrixReader.ReadBytes(matrixSize));
68 
69                     matrices.Add(new MatlabMatrix(matrixName, data));
70                 }
71             }
72         }
73     }
74 
75     return matrices;
76 }
View Code

  C#調用就更簡單了,上面那些實現只是一個幫助,你們之後能夠了解解析其餘相似的數據格式。看看調用的代碼:

 1 using MathNet.Numerics.LinearAlgebra;
 2 using MathNet.Numerics.Data.Matlab;
 3 
 4 //從collection.mat文件中,讀取第一個double矩陣
 5 Matrix<double> m = MatlabReader.Read<double>("collection.mat");
 6 
 7 //從collection.mat中讀取一個名稱爲 vd 的特定矩陣
 8 Matrix<double> m = MatlabReader.Read<double>("collection.mat", "vd");
 9 
10 //直接選擇轉換爲其餘格式
11 Matrix<Complex> m = MatlabReader.Read<Complex>("collection.mat");
12 
13 //將一個文件的全部矩陣及其名稱存入字典中
14 Dictionary<string,Matrix<double>> ms = MatlabReader.ReadAll<double>("collection.mat");
15 
16 //讀取名爲 Ad和vd 的矩陣到字典
17 var ms = MatlabReader.ReadAll<double>("collection.mat", "vd", "Ad");

  這樣就能夠直接在C#中進行相關計算了,也不用混合編程那麼麻煩了。

4.C#保存Mat數據格式

  Mat數據格式的寫入主要用MatlabWriter類,核心功能函數就是下面代碼:

 1 /// <summary>Writes all matrix blocks to a stream.</summary>
 2 internal static void FormatFile(Stream stream, IEnumerable<MatlabMatrix> matrices)
 3 {
 4     using (var buffer = new BufferedStream(stream))
 5     using (var writer = new BinaryWriter(buffer))
 6     {
 7         // write header and subsystem data offset (116+8 bytes)
 8         var header = Encoding.ASCII.GetBytes(HeaderText + DateTime.Now.ToString(Resources.MatlabDateHeaderFormat));
 9         writer.Write(header);
10         Pad(writer, 116 - header.Length + 8, 32);
11 
12         // write version (2 bytes)
13         writer.Write((short)0x100);
14 
15         // write little endian indicator (2 bytes)
16         writer.Write((byte)0x49);
17         writer.Write((byte)0x4D);
18 
19         foreach (var matrix in matrices)
20         {
21             // write data type
22             writer.Write((int)DataType.Compressed);
23 
24             // compress data
25             var compressedData = PackCompressedBlock(matrix.Data, DataType.Matrix);
26 
27             // write compressed data to file
28             writer.Write(compressedData.Length);
29             writer.Write(compressedData);
30         }
31 
32         writer.Flush();
33         writer.Close();
34     }
35 }
View Code

  C#調用也很簡單,調用的代碼以下:  

 1 var matrices = new List<MatlabMatrix>();
 2 m.Add(MatlabWriter.Pack(myFirstMatrix, "m1");
 3 m.Add(MatlabWriter.Pack(mySecondMatrix, "m2");
 4 MatlabWrier.Store("file.mat", matrices);
 5 
 6 //寫入單個的"myMatrix"矩陣,並命名爲"m1".
 7 MatlabWriter.Write("file.mat", myMatrix, "m1");
 8 
 9 //寫入多個矩陣,注意 矩陣列表 和 名稱列表
10 MatlabWriter.Write("file.mat", new[] { m1, m2 }, new[] { "m1", "m2" });
11 
12 //寫入字典矩陣,和讀取的原理相似
13 var dict = new Dictionary<string, Matrix<double>>();
14 dict.Add("m1", m1);
15 dict.Add("m2", m2);
16 MatlabWriter.Write("file.mat", dict);

5.資源

  接下來的文章將繼續介紹Math.NET的其餘功能。 

  若是本文資源或者文章顯示有問題,請參考 本文原文地址http://www.cnblogs.com/asxinyu/p/4265972.html

  寫篇文章不容易,若是對您有幫助,順手點個【推薦】吧。

本博客還有大量的.NET開源技術文章,您可能感興趣: 

1.開源Math.NET基礎數學類庫使用系列文章連接

2.開源C#彩票數據資料庫系列文章連接

3.開源的.NET平臺ORM組件文章:連接

4.其餘開源的.NET組件文章:連接

5..NET平臺機器學習組件-Infer.NET系列文章:連接

6.Matlab混合編程文章:連接 

相關文章
相關標籤/搜索