本人在09年使用該元件的時候,主要原因也是為了替代Matlab,進行相關數學計算,現在依然有很多人關注Matlab計算,特别是學生,而很多也在使用C#,是以這些人通常由于個人能力有限(無法精通某一個門語言來解決綜合問題),無法單純的通過C#或者Matlab來解決問題,就想通過混合程式設計來調用完成,其實本人也做過大量的Matlab.NET混合程式設計研究,而且也個人制作了一套視訊教程,編寫過很多文章,可以參考如下文章:
本部落格所有文章分類的總目錄:【總目錄】本部落格博文總目錄-實時更新
開源Math.NET基礎數學類庫使用總目錄:【目錄】開源Math.NET基礎數學類庫使用總目錄
前言
本人在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 }
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資料挖掘與機器學習,作者部落格:
http://www.cnblogs.com/asxinyu
E-mail:[email protected]